Coverage Report

Created: 2025-10-31 09:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/src/node_realm.cc
Line
Count
Source
1
#include "node_realm.h"
2
#include "env-inl.h"
3
4
#include "memory_tracker-inl.h"
5
#include "node_builtins.h"
6
#include "node_process.h"
7
#include "util.h"
8
9
namespace node {
10
11
using v8::Context;
12
using v8::EscapableHandleScope;
13
using v8::GCCallbackFlags;
14
using v8::GCType;
15
using v8::HandleScope;
16
using v8::Isolate;
17
using v8::Local;
18
using v8::MaybeLocal;
19
using v8::Object;
20
using v8::SnapshotCreator;
21
using v8::String;
22
using v8::Value;
23
24
Realm::Realm(Environment* env, v8::Local<v8::Context> context, Kind kind)
25
35
    : env_(env), isolate_(Isolate::GetCurrent()), kind_(kind) {
26
35
  context_.Reset(isolate_, context);
27
35
  env->AssignToContext(context, this, ContextInfo(""));
28
  // The environment can also purge empty wrappers in the check callback,
29
  // though that may be a bit excessive depending on usage patterns.
30
  // For now using the GC epilogue is adequate.
31
35
  isolate_->AddGCEpilogueCallback(PurgeEmptyCppgcWrappers, this);
32
35
}
33
34
35
Realm::~Realm() {
35
35
  isolate_->RemoveGCEpilogueCallback(PurgeEmptyCppgcWrappers, this);
36
35
  CHECK_EQ(base_object_count_, 0);
37
35
}
38
39
void Realm::PurgeEmptyCppgcWrappers(Isolate* isolate,
40
                                    GCType type,
41
                                    GCCallbackFlags flags,
42
2.38k
                                    void* data) {
43
2.38k
  Realm* realm = static_cast<Realm*>(data);
44
2.38k
  if (realm->should_purge_empty_cppgc_wrappers_) {
45
0
    realm->cppgc_wrapper_list_.PurgeEmpty();
46
0
    realm->should_purge_empty_cppgc_wrappers_ = false;
47
0
  }
48
2.38k
}
49
50
0
void Realm::MemoryInfo(MemoryTracker* tracker) const {
51
0
#define V(PropertyName, TypeName)                                              \
52
0
  tracker->TrackField(#PropertyName, PropertyName());
53
0
  PER_REALM_STRONG_PERSISTENT_VALUES(V)
54
0
#undef V
55
56
0
  tracker->TrackField("base_object_list", base_object_list_);
57
0
  tracker->TrackField("cppgc_wrapper_list", cppgc_wrapper_list_);
58
0
  tracker->TrackField("builtins_with_cache", builtins_with_cache);
59
0
  tracker->TrackField("builtins_without_cache", builtins_without_cache);
60
0
}
61
62
35
void Realm::CreateProperties() {
63
35
  HandleScope handle_scope(isolate_);
64
35
  Local<Context> ctx = context();
65
66
  // Store primordials setup by the per-context script in the environment.
67
35
  Local<Object> per_context_bindings =
68
35
      GetPerContextExports(ctx, env_->isolate_data()).ToLocalChecked();
69
35
  Local<Value> primordials =
70
35
      per_context_bindings->Get(ctx, env_->primordials_string())
71
35
          .ToLocalChecked();
72
35
  CHECK(primordials->IsObject());
73
35
  set_primordials(primordials.As<Object>());
74
75
35
  Local<String> prototype_string = env_->prototype_string();
76
77
35
#define V(EnvPropertyName, PrimordialsPropertyName)                            \
78
140
  {                                                                            \
79
140
    Local<Value> ctor =                                                        \
80
140
        primordials.As<Object>()                                               \
81
140
            ->Get(ctx,                                                         \
82
140
                  FIXED_ONE_BYTE_STRING(isolate(), PrimordialsPropertyName))   \
83
140
            .ToLocalChecked();                                                 \
84
140
    CHECK(ctor->IsObject());                                                   \
85
140
    Local<Value> prototype =                                                   \
86
140
        ctor.As<Object>()->Get(ctx, prototype_string).ToLocalChecked();        \
87
140
    CHECK(prototype->IsObject());                                              \
88
140
    set_##EnvPropertyName(prototype.As<Object>());                             \
89
140
  }
90
91
70
  V(primordials_safe_map_prototype_object, "SafeMap");
92
70
  V(primordials_safe_set_prototype_object, "SafeSet");
93
70
  V(primordials_safe_weak_map_prototype_object, "SafeWeakMap");
94
70
  V(primordials_safe_weak_set_prototype_object, "SafeWeakSet");
95
70
#undef V
96
97
  // TODO(legendecas): some methods probably doesn't need to be created with
98
  // process. Distinguish them and create process object only in the principal
99
  // realm.
100
70
  Local<Object> process_object =
101
70
      node::CreateProcessObject(this).FromMaybe(Local<Object>());
102
70
  set_process_object(process_object);
103
70
}
104
105
0
RealmSerializeInfo Realm::Serialize(SnapshotCreator* creator) {
106
0
  RealmSerializeInfo info;
107
0
  Local<Context> ctx = context();
108
109
  // Currently all modules are compiled without cache in builtin snapshot
110
  // builder.
111
0
  info.builtins = std::vector<std::string>(builtins_without_cache.begin(),
112
0
                                           builtins_without_cache.end());
113
114
0
  uint32_t id = 0;
115
0
#define V(PropertyName, TypeName)                                              \
116
0
  do {                                                                         \
117
0
    Local<TypeName> field = PropertyName();                                    \
118
0
    if (!field.IsEmpty()) {                                                    \
119
0
      size_t index = creator->AddData(ctx, field);                             \
120
0
      info.persistent_values.push_back({#PropertyName, id, index});            \
121
0
    }                                                                          \
122
0
    id++;                                                                      \
123
0
  } while (0);
124
0
  PER_REALM_STRONG_PERSISTENT_VALUES(V)
125
0
#undef V
126
127
  // Do this after other creator->AddData() calls so that Snapshotable objects
128
  // can use 0 to indicate that a SnapshotIndex is invalid.
129
0
  SerializeSnapshotableObjects(this, creator, &info);
130
131
0
  info.context = creator->AddData(ctx, ctx);
132
0
  return info;
133
0
}
134
135
0
void Realm::DeserializeProperties(const RealmSerializeInfo* info) {
136
0
  Local<Context> ctx = context();
137
138
0
  builtins_in_snapshot = info->builtins;
139
140
0
  const std::vector<PropInfo>& values = info->persistent_values;
141
0
  size_t i = 0;  // index to the array
142
0
  uint32_t id = 0;
143
0
#define V(PropertyName, TypeName)                                              \
144
0
  do {                                                                         \
145
0
    if (values.size() > i && id == values[i].id) {                             \
146
0
      const PropInfo& d = values[i];                                           \
147
0
      DCHECK_EQ(d.name, #PropertyName);                                        \
148
0
      MaybeLocal<TypeName> maybe_field =                                       \
149
0
          ctx->GetDataFromSnapshotOnce<TypeName>(d.index);                     \
150
0
      Local<TypeName> field;                                                   \
151
0
      if (!maybe_field.ToLocal(&field)) {                                      \
152
0
        fprintf(stderr,                                                        \
153
0
                "Failed to deserialize realm value " #PropertyName "\n");      \
154
0
      }                                                                        \
155
0
      set_##PropertyName(field);                                               \
156
0
      i++;                                                                     \
157
0
    }                                                                          \
158
0
    id++;                                                                      \
159
0
  } while (0);
160
161
0
  PER_REALM_STRONG_PERSISTENT_VALUES(V);
162
0
#undef V
163
164
0
  MaybeLocal<Context> maybe_ctx_from_snapshot =
165
0
      ctx->GetDataFromSnapshotOnce<Context>(info->context);
166
0
  Local<Context> ctx_from_snapshot;
167
0
  if (!maybe_ctx_from_snapshot.ToLocal(&ctx_from_snapshot)) {
168
0
    fprintf(stderr,
169
0
            "Failed to deserialize context back reference from the snapshot\n");
170
0
  }
171
0
  CHECK_EQ(ctx_from_snapshot, ctx);
172
173
0
  DoneBootstrapping();
174
0
}
175
176
245
MaybeLocal<Value> Realm::ExecuteBootstrapper(const char* id) {
177
245
  EscapableHandleScope scope(isolate());
178
245
  Local<Context> ctx = context();
179
245
  MaybeLocal<Value> result =
180
245
      env()->builtin_loader()->CompileAndCall(ctx, id, this);
181
182
  // If there was an error during bootstrap, it must be unrecoverable
183
  // (e.g. max call stack exceeded). Clear the stack so that the
184
  // AsyncCallbackScope destructor doesn't fail on the id check.
185
  // There are only two ways to have a stack size > 1: 1) the user manually
186
  // called MakeCallback or 2) user awaited during bootstrap, which triggered
187
  // _tickCallback().
188
245
  if (result.IsEmpty()) {
189
0
    env()->async_hooks()->clear_async_id_stack();
190
0
  }
191
192
245
  return scope.EscapeMaybe(result);
193
245
}
194
195
35
MaybeLocal<Value> Realm::RunBootstrapping() {
196
35
  EscapableHandleScope scope(isolate_);
197
198
35
  CHECK(!has_run_bootstrapping_code());
199
200
35
  Local<Value> result;
201
35
  if (!ExecuteBootstrapper("internal/bootstrap/realm").ToLocal(&result) ||
202
35
      !BootstrapRealm().ToLocal(&result)) {
203
0
    return MaybeLocal<Value>();
204
0
  }
205
206
35
  DoneBootstrapping();
207
208
35
  return scope.Escape(result);
209
35
}
210
211
35
void Realm::DoneBootstrapping() {
212
  // Make sure that no request or handle is created during bootstrap -
213
  // if necessary those should be done in pre-execution.
214
  // Usually, doing so would trigger the checks present in the ReqWrap and
215
  // HandleWrap classes, so this is only a consistency check.
216
217
  // TODO(legendecas): track req_wrap and handle_wrap by realms instead of
218
  // environments.
219
35
  if (kind_ == kPrincipal) {
220
35
    CHECK(env_->req_wrap_queue()->IsEmpty());
221
35
    CHECK(env_->handle_wrap_queue()->IsEmpty());
222
35
  }
223
224
35
  has_run_bootstrapping_code_ = true;
225
226
  // This adjusts the return value of base_object_created_after_bootstrap() so
227
  // that tests that check the count do not have to account for internally
228
  // created BaseObjects.
229
35
  base_object_created_by_bootstrap_ = base_object_count_;
230
35
}
231
232
35
void Realm::RunCleanup() {
233
35
  TRACE_EVENT0(TRACING_CATEGORY_NODE1(realm), "RunCleanup");
234
455
  for (size_t i = 0; i < binding_data_store_.size(); ++i) {
235
420
    binding_data_store_[i].reset();
236
420
  }
237
35
  base_object_list_.Cleanup();
238
35
  cppgc_wrapper_list_.Cleanup();
239
35
}
240
241
0
void Realm::PrintInfoForSnapshot() {
242
0
  fprintf(stderr, "Realm = %p\n", this);
243
0
  fprintf(stderr, "BaseObjects of the Realm:\n");
244
0
  size_t i = 0;
245
0
  ForEachBaseObject([&](BaseObject* obj) {
246
0
    std::cerr << "#" << i++ << " " << obj << ": " << obj->MemoryInfoName()
247
0
              << "\n";
248
0
  });
249
250
0
  fprintf(stderr, "\nBuiltins without cache:\n");
251
0
  for (const auto& s : builtins_without_cache) {
252
0
    fprintf(stderr, "%s\n", s.c_str());
253
0
  }
254
0
  fprintf(stderr, "\nBuiltins with cache:\n");
255
0
  for (const auto& s : builtins_with_cache) {
256
0
    fprintf(stderr, "%s\n", s.c_str());
257
0
  }
258
0
  fprintf(stderr, "\nStatic bindings (need to be registered):\n");
259
0
  for (const auto mod : internal_bindings) {
260
0
    fprintf(stderr, "%s:%s\n", mod->nm_filename, mod->nm_modname);
261
0
  }
262
263
0
  fprintf(stderr, "End of the Realm.\n");
264
0
}
265
266
0
void Realm::VerifyNoStrongBaseObjects() {
267
  // When a process exits cleanly, i.e. because the event loop ends up without
268
  // things to wait for, the Node.js objects that are left on the heap should
269
  // be:
270
  //
271
  //   1. weak, i.e. ready for garbage collection once no longer referenced, or
272
  //   2. detached, i.e. scheduled for destruction once no longer referenced, or
273
  //   3. an unrefed libuv handle, i.e. does not keep the event loop alive, or
274
  //   4. an inactive libuv handle (essentially the same here)
275
  //
276
  // There are a few exceptions to this rule, but generally, if there are
277
  // C++-backed Node.js objects on the heap that do not fall into the above
278
  // categories, we may be looking at a potential memory leak. Most likely,
279
  // the cause is a missing MakeWeak() call on the corresponding object.
280
  //
281
  // In order to avoid this kind of problem, we check the list of BaseObjects
282
  // for these criteria. Currently, we only do so when explicitly instructed to
283
  // or when in debug mode (where --verify-base-objects is always-on).
284
285
  // TODO(legendecas): introduce per-realm options.
286
0
  if (!env()->options()->verify_base_objects) return;
287
288
0
  ForEachBaseObject([](BaseObject* obj) {
289
0
    if (obj->IsNotIndicativeOfMemoryLeakAtExit()) return;
290
0
    fprintf(stderr,
291
0
            "Found bad BaseObject during clean exit: %s\n",
292
0
            obj->MemoryInfoName());
293
0
    fflush(stderr);
294
0
    ABORT();
295
0
  });
296
0
}
297
298
1.48M
v8::Local<v8::Context> Realm::context() const {
299
1.48M
  return PersistentToLocal::Strong(context_);
300
1.48M
}
301
302
// Per-realm strong value accessors. The per-realm values should avoid being
303
// accessed across realms.
304
#define V(PropertyName, TypeName)                                              \
305
981
  v8::Local<TypeName> PrincipalRealm::PropertyName() const {                   \
306
981
    return PersistentToLocal::Strong(PropertyName##_);                         \
307
981
  }                                                                            \
Unexecuted instantiation: node::PrincipalRealm::async_hooks_after_function() const
Unexecuted instantiation: node::PrincipalRealm::async_hooks_before_function() const
Unexecuted instantiation: node::PrincipalRealm::async_hooks_callback_trampoline() const
Unexecuted instantiation: node::PrincipalRealm::async_hooks_binding() const
Unexecuted instantiation: node::PrincipalRealm::async_hooks_destroy_function() const
node::PrincipalRealm::async_hooks_init_function() const
Line
Count
Source
305
35
  v8::Local<TypeName> PrincipalRealm::PropertyName() const {                   \
306
35
    return PersistentToLocal::Strong(PropertyName##_);                         \
307
35
  }                                                                            \
Unexecuted instantiation: node::PrincipalRealm::async_hooks_promise_resolve_function() const
Unexecuted instantiation: node::PrincipalRealm::buffer_prototype_object() const
Unexecuted instantiation: node::PrincipalRealm::crypto_key_object_private_constructor() const
Unexecuted instantiation: node::PrincipalRealm::crypto_key_object_public_constructor() const
Unexecuted instantiation: node::PrincipalRealm::crypto_key_object_secret_constructor() const
Unexecuted instantiation: node::PrincipalRealm::enhance_fatal_stack_after_inspector() const
Unexecuted instantiation: node::PrincipalRealm::enhance_fatal_stack_before_inspector() const
Unexecuted instantiation: node::PrincipalRealm::get_source_map_error_source() const
Unexecuted instantiation: node::PrincipalRealm::host_import_module_dynamically_callback() const
Unexecuted instantiation: node::PrincipalRealm::host_initialize_import_meta_object_callback() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_altsvc_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_error_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_frame_error_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_goaway_data_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_headers_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_origin_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_ping_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_priority_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_settings_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_stream_close_function() const
Unexecuted instantiation: node::PrincipalRealm::http2session_on_stream_trailers_function() const
node::PrincipalRealm::internal_binding_loader() const
Line
Count
Source
305
210
  v8::Local<TypeName> PrincipalRealm::PropertyName() const {                   \
306
210
    return PersistentToLocal::Strong(PropertyName##_);                         \
307
210
  }                                                                            \
Unexecuted instantiation: node::PrincipalRealm::immediate_callback_function() const
Unexecuted instantiation: node::PrincipalRealm::inspector_console_extension_installer() const
Unexecuted instantiation: node::PrincipalRealm::inspector_disable_async_hooks() const
Unexecuted instantiation: node::PrincipalRealm::inspector_disable_network_tracking() const
Unexecuted instantiation: node::PrincipalRealm::inspector_enable_async_hooks() const
Unexecuted instantiation: node::PrincipalRealm::inspector_enable_network_tracking() const
Unexecuted instantiation: node::PrincipalRealm::maybe_cache_generated_source_map() const
Unexecuted instantiation: node::PrincipalRealm::messaging_deserialize_create_object() const
Unexecuted instantiation: node::PrincipalRealm::message_port() const
node::PrincipalRealm::builtin_module_require() const
Line
Count
Source
305
211
  v8::Local<TypeName> PrincipalRealm::PropertyName() const {                   \
306
211
    return PersistentToLocal::Strong(PropertyName##_);                         \
307
211
  }                                                                            \
Unexecuted instantiation: node::PrincipalRealm::performance_entry_callback() const
Unexecuted instantiation: node::PrincipalRealm::prepare_stack_trace_callback() const
node::PrincipalRealm::process_object() const
Line
Count
Source
305
280
  v8::Local<TypeName> PrincipalRealm::PropertyName() const {                   \
306
280
    return PersistentToLocal::Strong(PropertyName##_);                         \
307
280
  }                                                                            \
Unexecuted instantiation: node::PrincipalRealm::process_emit_warning_sync() const
node::PrincipalRealm::primordials() const
Line
Count
Source
305
245
  v8::Local<TypeName> PrincipalRealm::PropertyName() const {                   \
306
245
    return PersistentToLocal::Strong(PropertyName##_);                         \
307
245
  }                                                                            \
Unexecuted instantiation: node::PrincipalRealm::primordials_safe_map_prototype_object() const
Unexecuted instantiation: node::PrincipalRealm::primordials_safe_set_prototype_object() const
Unexecuted instantiation: node::PrincipalRealm::primordials_safe_weak_map_prototype_object() const
Unexecuted instantiation: node::PrincipalRealm::primordials_safe_weak_set_prototype_object() const
Unexecuted instantiation: node::PrincipalRealm::promise_reject_callback() const
Unexecuted instantiation: node::PrincipalRealm::snapshot_serialize_callback() const
Unexecuted instantiation: node::PrincipalRealm::snapshot_deserialize_callback() const
Unexecuted instantiation: node::PrincipalRealm::snapshot_deserialize_main() const
Unexecuted instantiation: node::PrincipalRealm::source_map_cache_getter() const
Unexecuted instantiation: node::PrincipalRealm::tick_callback_function() const
Unexecuted instantiation: node::PrincipalRealm::timers_callback_function() const
Unexecuted instantiation: node::PrincipalRealm::tls_wrap_constructor_function() const
Unexecuted instantiation: node::PrincipalRealm::trace_category_state_function() const
Unexecuted instantiation: node::PrincipalRealm::udp_constructor_function() const
Unexecuted instantiation: node::PrincipalRealm::wasm_streaming_compilation_impl() const
Unexecuted instantiation: node::PrincipalRealm::wasm_streaming_object_constructor() const
308
1.33k
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
1.33k
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
1.33k
                   isolate()->GetCurrentContext() == context());               \
311
1.33k
    PropertyName##_.Reset(isolate(), value);                                   \
312
1.33k
  }
node::PrincipalRealm::set_async_hooks_after_function(v8::Local<v8::Function>)
Line
Count
Source
308
70
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
70
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
70
                   isolate()->GetCurrentContext() == context());               \
311
70
    PropertyName##_.Reset(isolate(), value);                                   \
312
70
  }
node::PrincipalRealm::set_async_hooks_before_function(v8::Local<v8::Function>)
Line
Count
Source
308
70
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
70
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
70
                   isolate()->GetCurrentContext() == context());               \
311
70
    PropertyName##_.Reset(isolate(), value);                                   \
312
70
  }
node::PrincipalRealm::set_async_hooks_callback_trampoline(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_async_hooks_binding(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_async_hooks_destroy_function(v8::Local<v8::Function>)
Line
Count
Source
308
70
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
70
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
70
                   isolate()->GetCurrentContext() == context());               \
311
70
    PropertyName##_.Reset(isolate(), value);                                   \
312
70
  }
node::PrincipalRealm::set_async_hooks_init_function(v8::Local<v8::Function>)
Line
Count
Source
308
70
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
70
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
70
                   isolate()->GetCurrentContext() == context());               \
311
70
    PropertyName##_.Reset(isolate(), value);                                   \
312
70
  }
node::PrincipalRealm::set_async_hooks_promise_resolve_function(v8::Local<v8::Function>)
Line
Count
Source
308
70
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
70
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
70
                   isolate()->GetCurrentContext() == context());               \
311
70
    PropertyName##_.Reset(isolate(), value);                                   \
312
70
  }
node::PrincipalRealm::set_buffer_prototype_object(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_crypto_key_object_private_constructor(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_crypto_key_object_public_constructor(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_crypto_key_object_secret_constructor(v8::Local<v8::Function>)
node::PrincipalRealm::set_enhance_fatal_stack_after_inspector(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_enhance_fatal_stack_before_inspector(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_get_source_map_error_source(v8::Local<v8::Function>)
node::PrincipalRealm::set_host_import_module_dynamically_callback(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_host_initialize_import_meta_object_callback(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_altsvc_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_error_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_frame_error_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_goaway_data_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_headers_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_origin_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_ping_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_priority_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_settings_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_stream_close_function(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_http2session_on_stream_trailers_function(v8::Local<v8::Function>)
node::PrincipalRealm::set_internal_binding_loader(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_immediate_callback_function(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_inspector_console_extension_installer(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_inspector_disable_async_hooks(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_inspector_disable_network_tracking(v8::Local<v8::Function>)
node::PrincipalRealm::set_inspector_enable_async_hooks(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_inspector_enable_network_tracking(v8::Local<v8::Function>)
node::PrincipalRealm::set_maybe_cache_generated_source_map(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_messaging_deserialize_create_object(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_message_port(v8::Local<v8::Object>)
node::PrincipalRealm::set_builtin_module_require(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_performance_entry_callback(v8::Local<v8::Function>)
node::PrincipalRealm::set_prepare_stack_trace_callback(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_process_object(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_process_emit_warning_sync(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_primordials(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_primordials_safe_map_prototype_object(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_primordials_safe_set_prototype_object(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_primordials_safe_weak_map_prototype_object(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_primordials_safe_weak_set_prototype_object(v8::Local<v8::Object>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_promise_reject_callback(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_snapshot_serialize_callback(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_snapshot_deserialize_callback(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_snapshot_deserialize_main(v8::Local<v8::Function>)
Unexecuted instantiation: node::PrincipalRealm::set_source_map_cache_getter(v8::Local<v8::Function>)
node::PrincipalRealm::set_tick_callback_function(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
node::PrincipalRealm::set_timers_callback_function(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_tls_wrap_constructor_function(v8::Local<v8::Function>)
node::PrincipalRealm::set_trace_category_state_function(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_udp_constructor_function(v8::Local<v8::Function>)
node::PrincipalRealm::set_wasm_streaming_compilation_impl(v8::Local<v8::Function>)
Line
Count
Source
308
35
  void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) {         \
309
35
    DCHECK_IMPLIES(!value.IsEmpty(),                                           \
310
35
                   isolate()->GetCurrentContext() == context());               \
311
35
    PropertyName##_.Reset(isolate(), value);                                   \
312
35
  }
Unexecuted instantiation: node::PrincipalRealm::set_wasm_streaming_object_constructor(v8::Local<v8::Function>)
313
PER_REALM_STRONG_PERSISTENT_VALUES(V)
314
#undef V
315
316
PrincipalRealm::PrincipalRealm(Environment* env,
317
                               v8::Local<v8::Context> context,
318
                               const RealmSerializeInfo* realm_info)
319
35
    : Realm(env, context, kPrincipal) {
320
  // Create properties if not deserializing from snapshot.
321
  // Or the properties are deserialized with DeserializeProperties() when the
322
  // env drained the deserialize requests.
323
35
  if (realm_info == nullptr) {
324
35
    CreateProperties();
325
35
  }
326
35
}
327
328
35
PrincipalRealm::~PrincipalRealm() {
329
35
  DCHECK(!context_.IsEmpty());
330
331
35
  HandleScope handle_scope(isolate());
332
35
  env_->UnassignFromContext(context());
333
35
}
334
335
35
MaybeLocal<Value> PrincipalRealm::BootstrapRealm() {
336
35
  HandleScope scope(isolate_);
337
338
35
  if (ExecuteBootstrapper("internal/bootstrap/node").IsEmpty()) {
339
0
    return MaybeLocal<Value>();
340
0
  }
341
342
35
  if (!env_->no_browser_globals()) {
343
35
    if (ExecuteBootstrapper("internal/bootstrap/web/exposed-wildcard")
344
35
            .IsEmpty() ||
345
35
        ExecuteBootstrapper("internal/bootstrap/web/exposed-window-or-worker")
346
35
            .IsEmpty()) {
347
0
      return MaybeLocal<Value>();
348
0
    }
349
35
  }
350
351
  // TODO(joyeecheung): skip these in the snapshot building for workers.
352
35
  auto thread_switch_id =
353
35
      env_->is_main_thread() ? "internal/bootstrap/switches/is_main_thread"
354
35
                             : "internal/bootstrap/switches/is_not_main_thread";
355
35
  if (ExecuteBootstrapper(thread_switch_id).IsEmpty()) {
356
0
    return MaybeLocal<Value>();
357
0
  }
358
359
35
  auto process_state_switch_id =
360
35
      env_->owns_process_state()
361
35
          ? "internal/bootstrap/switches/does_own_process_state"
362
35
          : "internal/bootstrap/switches/does_not_own_process_state";
363
35
  if (ExecuteBootstrapper(process_state_switch_id).IsEmpty()) {
364
0
    return MaybeLocal<Value>();
365
0
  }
366
367
  // Setup process.env proxy.
368
35
  Local<String> env_string = FIXED_ONE_BYTE_STRING(isolate_, "env");
369
35
  Local<Object> env_proxy;
370
35
  if (!isolate_data()->env_proxy_template()->NewInstance(context()).ToLocal(
371
35
          &env_proxy) ||
372
35
      process_object()->Set(context(), env_string, env_proxy).IsNothing()) {
373
0
    return MaybeLocal<Value>();
374
0
  }
375
376
35
  return v8::True(isolate_);
377
35
}
378
379
}  // namespace node