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