GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_main_instance.cc Lines: 87 88 98.9 %
Date: 2022-09-21 04:23:13 Branches: 31 40 77.5 %

Line Branch Exec Source
1
#include "node_main_instance.h"
2
#include <memory>
3
#if HAVE_OPENSSL
4
#include "crypto/crypto_util.h"
5
#endif  // HAVE_OPENSSL
6
#include "debug_utils-inl.h"
7
#include "node_builtins.h"
8
#include "node_external_reference.h"
9
#include "node_internals.h"
10
#include "node_options-inl.h"
11
#include "node_realm.h"
12
#include "node_snapshot_builder.h"
13
#include "node_snapshotable.h"
14
#include "node_v8_platform-inl.h"
15
#include "util-inl.h"
16
#if defined(LEAK_SANITIZER)
17
#include <sanitizer/lsan_interface.h>
18
#endif
19
20
#if HAVE_INSPECTOR
21
#include "inspector/worker_inspector.h"  // ParentInspectorHandle
22
#endif
23
24
namespace node {
25
26
using v8::Context;
27
using v8::HandleScope;
28
using v8::Isolate;
29
using v8::Local;
30
using v8::Locker;
31
32
7
NodeMainInstance::NodeMainInstance(Isolate* isolate,
33
                                   uv_loop_t* event_loop,
34
                                   MultiIsolatePlatform* platform,
35
                                   const std::vector<std::string>& args,
36
7
                                   const std::vector<std::string>& exec_args)
37
    : args_(args),
38
      exec_args_(exec_args),
39
      array_buffer_allocator_(nullptr),
40
      isolate_(isolate),
41
      platform_(platform),
42
      isolate_data_(nullptr),
43
7
      snapshot_data_(nullptr) {
44
  isolate_data_ =
45
7
      std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
46
47
7
  SetIsolateMiscHandlers(isolate_, {});
48
7
}
49
50
7
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
51
    Isolate* isolate,
52
    uv_loop_t* event_loop,
53
    MultiIsolatePlatform* platform,
54
    const std::vector<std::string>& args,
55
    const std::vector<std::string>& exec_args) {
56
  return std::unique_ptr<NodeMainInstance>(
57
7
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
58
}
59
60
5522
NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
61
                                   uv_loop_t* event_loop,
62
                                   MultiIsolatePlatform* platform,
63
                                   const std::vector<std::string>& args,
64
5522
                                   const std::vector<std::string>& exec_args)
65
    : args_(args),
66
      exec_args_(exec_args),
67
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
68
      isolate_(nullptr),
69
      platform_(platform),
70
      isolate_data_(),
71
      isolate_params_(std::make_unique<Isolate::CreateParams>()),
72
5522
      snapshot_data_(snapshot_data) {
73
5522
  isolate_params_->array_buffer_allocator = array_buffer_allocator_.get();
74
5522
  if (snapshot_data != nullptr) {
75
5520
    SnapshotBuilder::InitializeIsolateParams(snapshot_data,
76
                                             isolate_params_.get());
77
  }
78
79
5522
  isolate_ = Isolate::Allocate();
80
5522
  CHECK_NOT_NULL(isolate_);
81
  // Register the isolate on the platform before the isolate gets initialized,
82
  // so that the isolate can access the platform during initialization.
83
5522
  platform->RegisterIsolate(isolate_, event_loop);
84
5522
  SetIsolateCreateParamsForNode(isolate_params_.get());
85
5522
  Isolate::Initialize(isolate_, *isolate_params_);
86
87
  // If the indexes are not nullptr, we are not deserializing
88
5522
  isolate_data_ = std::make_unique<IsolateData>(
89
5522
      isolate_,
90
      event_loop,
91
      platform,
92
5522
      array_buffer_allocator_.get(),
93
11044
      snapshot_data == nullptr ? nullptr : &(snapshot_data->isolate_data_info));
94
5522
  IsolateSettings s;
95
5522
  SetIsolateMiscHandlers(isolate_, s);
96
5522
  if (snapshot_data == nullptr) {
97
    // If in deserialize mode, delay until after the deserialization is
98
    // complete.
99
2
    SetIsolateErrorHandlers(isolate_, s);
100
  }
101
5522
  isolate_data_->max_young_gen_size =
102
5522
      isolate_params_->constraints.max_young_generation_size_in_bytes();
103
5522
}
104
105
7
void NodeMainInstance::Dispose() {
106
  // This should only be called on a main instance that does not own its
107
  // isolate.
108
7
  CHECK_NULL(isolate_params_);
109
7
  platform_->DrainTasks(isolate_);
110
7
}
111
112


4898
NodeMainInstance::~NodeMainInstance() {
113
4870
  if (isolate_params_ == nullptr) {
114
7
    return;
115
  }
116
  // This should only be done on a main instance that owns its isolate.
117
4863
  platform_->UnregisterIsolate(isolate_);
118
4863
  isolate_->Dispose();
119
4870
}
120
121
5522
int NodeMainInstance::Run() {
122
10385
  Locker locker(isolate_);
123
10385
  Isolate::Scope isolate_scope(isolate_);
124
10385
  HandleScope handle_scope(isolate_);
125
126
5522
  int exit_code = 0;
127
  DeleteFnPtr<Environment, FreeEnvironment> env =
128
10385
      CreateMainEnvironment(&exit_code);
129
5522
  CHECK_NOT_NULL(env);
130
131
5522
  Context::Scope context_scope(env->context());
132
5522
  Run(&exit_code, env.get());
133
4863
  return exit_code;
134
}
135
136
5522
void NodeMainInstance::Run(int* exit_code, Environment* env) {
137
5522
  if (*exit_code == 0) {
138
5522
    LoadEnvironment(env, StartExecutionCallback{});
139
140
10067
    *exit_code = SpinEventLoop(env).FromMaybe(1);
141
  }
142
143
#if defined(LEAK_SANITIZER)
144
  __lsan_do_leak_check();
145
#endif
146
4863
}
147
148
DeleteFnPtr<Environment, FreeEnvironment>
149
5522
NodeMainInstance::CreateMainEnvironment(int* exit_code) {
150
5522
  *exit_code = 0;  // Reset the exit code to 0
151
152
11044
  HandleScope handle_scope(isolate_);
153
154
  // TODO(addaleax): This should load a real per-Isolate option, currently
155
  // this is still effectively per-process.
156
5522
  if (isolate_data_->options()->track_heap_objects) {
157
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
158
  }
159
160
  Local<Context> context;
161
5522
  DeleteFnPtr<Environment, FreeEnvironment> env;
162
163
5522
  if (snapshot_data_ != nullptr) {
164
11040
    env.reset(new Environment(isolate_data_.get(),
165
                              isolate_,
166
5520
                              args_,
167
5520
                              exec_args_,
168
5520
                              &(snapshot_data_->env_info),
169
                              EnvironmentFlags::kDefaultFlags,
170
5520
                              {}));
171
5520
    context = Context::FromSnapshot(isolate_,
172
                                    SnapshotData::kNodeMainContextIndex,
173
5520
                                    {DeserializeNodeInternalFields, env.get()})
174
5520
                  .ToLocalChecked();
175
176
5520
    CHECK(!context.IsEmpty());
177
5520
    Context::Scope context_scope(context);
178
179
11040
    CHECK(InitializeContextRuntime(context).IsJust());
180
5520
    SetIsolateErrorHandlers(isolate_, {});
181
5520
    env->InitializeMainContext(context, &(snapshot_data_->env_info));
182
#if HAVE_INSPECTOR
183
5520
    env->InitializeInspector({});
184
#endif
185
186
#if HAVE_OPENSSL
187
5520
    crypto::InitCryptoOnce(isolate_);
188
#endif  // HAVE_OPENSSL
189
  } else {
190
2
    context = NewContext(isolate_);
191
2
    CHECK(!context.IsEmpty());
192
2
    Context::Scope context_scope(context);
193
4
    env.reset(new Environment(isolate_data_.get(),
194
                              context,
195
2
                              args_,
196
2
                              exec_args_,
197
                              nullptr,
198
                              EnvironmentFlags::kDefaultFlags,
199
2
                              {}));
200
#if HAVE_INSPECTOR
201
2
    env->InitializeInspector({});
202
#endif
203
4
    if (env->principal_realm()->RunBootstrapping().IsEmpty()) {
204
      return nullptr;
205
    }
206
  }
207
208
5522
  return env;
209
}
210
211
}  // namespace node