|
| 1 | +#include "snapshot_builder.h" |
| 2 | +#include <iostream> |
| 3 | +#include <sstream> |
| 4 | +#include "env-inl.h" |
| 5 | +#include "node_internals.h" |
| 6 | +#include "node_main_instance.h" |
| 7 | +#include "node_v8_platform-inl.h" |
| 8 | + |
| 9 | +namespace node { |
| 10 | + |
| 11 | +using v8::Context; |
| 12 | +using v8::HandleScope; |
| 13 | +using v8::Isolate; |
| 14 | +using v8::Local; |
| 15 | +using v8::Locker; |
| 16 | +using v8::SnapshotCreator; |
| 17 | +using v8::StartupData; |
| 18 | + |
| 19 | +std::string FormatBlob(v8::StartupData* blob, |
| 20 | + const std::vector<size_t>& isolate_data_indexes) { |
| 21 | + std::stringstream ss; |
| 22 | + size_t isolate_data_indexes_size = isolate_data_indexes.size(); |
| 23 | + |
| 24 | + ss << R"(#include <cstddef> |
| 25 | +#include "node_main_instance.h" |
| 26 | +#include "v8.h" |
| 27 | +
|
| 28 | +// This file is generated by tools/snapshot. Do not edit. |
| 29 | +
|
| 30 | +namespace node { |
| 31 | +
|
| 32 | +static const uint8_t blob_data[] = { |
| 33 | +)"; |
| 34 | + |
| 35 | + for (int i = 0; i < blob->raw_size; i++) { |
| 36 | + uint8_t ch = blob->data[i]; |
| 37 | + ss << std::to_string(ch) << ((i == blob->raw_size - 1) ? '\n' : ','); |
| 38 | + } |
| 39 | + |
| 40 | + ss << R"(}; |
| 41 | +
|
| 42 | +static const int blob_size = )" |
| 43 | + << blob->raw_size << R"(; |
| 44 | +static v8::StartupData blob = { |
| 45 | + reinterpret_cast<const char*>(blob_data), |
| 46 | + blob_size |
| 47 | +}; |
| 48 | +)"; |
| 49 | + |
| 50 | + ss << R"(v8::StartupData* |
| 51 | +NodeMainInstance::GetEmbeddedSnapshotBlob() { |
| 52 | + return &blob; |
| 53 | +} |
| 54 | +
|
| 55 | +static const size_t isolate_data_indexes_raw[] = { |
| 56 | +)"; |
| 57 | + for (size_t i = 0; i < isolate_data_indexes_size; i++) { |
| 58 | + ss << std::to_string(isolate_data_indexes[i]) |
| 59 | + << ((i == isolate_data_indexes_size - 1) ? '\n' : ','); |
| 60 | + } |
| 61 | + ss << "};\n\n"; |
| 62 | + |
| 63 | + ss << "static const size_t isolate_data_indexes_size = " |
| 64 | + << isolate_data_indexes_size << R"(; |
| 65 | +
|
| 66 | +NodeMainInstance::IndexArray isolate_data_indexes { |
| 67 | + isolate_data_indexes_raw, |
| 68 | + isolate_data_indexes_size |
| 69 | +}; |
| 70 | +
|
| 71 | +const NodeMainInstance::IndexArray* |
| 72 | +NodeMainInstance::GetIsolateDataIndexes() { |
| 73 | + return &isolate_data_indexes; |
| 74 | +} |
| 75 | +} // namespace node |
| 76 | +)"; |
| 77 | + |
| 78 | + return ss.str(); |
| 79 | +} |
| 80 | + |
| 81 | +std::string SnapshotBuilder::Generate( |
| 82 | + const std::vector<std::string> args, |
| 83 | + const std::vector<std::string> exec_args) { |
| 84 | + // TODO(joyeecheung): collect external references and set it in |
| 85 | + // params.external_references. |
| 86 | + std::vector<intptr_t> external_references = { |
| 87 | + reinterpret_cast<intptr_t>(nullptr)}; |
| 88 | + Isolate* isolate = Isolate::Allocate(); |
| 89 | + per_process::v8_platform.Platform()->RegisterIsolate(isolate, |
| 90 | + uv_default_loop()); |
| 91 | + NodeMainInstance* main_instance = nullptr; |
| 92 | + std::string result; |
| 93 | + |
| 94 | + { |
| 95 | + std::vector<size_t> isolate_data_indexes; |
| 96 | + SnapshotCreator creator(isolate, external_references.data()); |
| 97 | + { |
| 98 | + main_instance = |
| 99 | + NodeMainInstance::Create(isolate, |
| 100 | + uv_default_loop(), |
| 101 | + per_process::v8_platform.Platform(), |
| 102 | + args, |
| 103 | + exec_args); |
| 104 | + HandleScope scope(isolate); |
| 105 | + creator.SetDefaultContext(Context::New(isolate)); |
| 106 | + isolate_data_indexes = main_instance->isolate_data()->Serialize(&creator); |
| 107 | + } |
| 108 | + |
| 109 | + // Must be out of HandleScope |
| 110 | + StartupData blob = |
| 111 | + creator.CreateBlob(SnapshotCreator::FunctionCodeHandling::kClear); |
| 112 | + // Must be done while the snapshot creator isolate is entered i.e. the |
| 113 | + // creator is still alive. |
| 114 | + main_instance->Dispose(); |
| 115 | + result = FormatBlob(&blob, isolate_data_indexes); |
| 116 | + delete blob.data; |
| 117 | + } |
| 118 | + |
| 119 | + per_process::v8_platform.Platform()->UnregisterIsolate(isolate); |
| 120 | + return result; |
| 121 | +} |
| 122 | +} // namespace node |
0 commit comments