/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.25k | void* data) { |
43 | 2.25k | Realm* realm = static_cast<Realm*>(data); |
44 | 2.25k | 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.25k | } |
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 | | // Per-realm strong value accessors. The per-realm values should avoid being |
299 | | // accessed across realms. |
300 | | #define V(PropertyName, TypeName) \ |
301 | 982 | v8::Local<TypeName> PrincipalRealm::PropertyName() const { \ |
302 | 982 | return PersistentToLocal::Strong(PropertyName##_); \ |
303 | 982 | } \ 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 | 301 | 35 | v8::Local<TypeName> PrincipalRealm::PropertyName() const { \ | 302 | 35 | return PersistentToLocal::Strong(PropertyName##_); \ | 303 | 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_import_meta_resolve_initializer() 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 | 301 | 210 | v8::Local<TypeName> PrincipalRealm::PropertyName() const { \ | 302 | 210 | return PersistentToLocal::Strong(PropertyName##_); \ | 303 | 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 | 301 | 212 | v8::Local<TypeName> PrincipalRealm::PropertyName() const { \ | 302 | 212 | return PersistentToLocal::Strong(PropertyName##_); \ | 303 | 212 | } \ |
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 | 301 | 280 | v8::Local<TypeName> PrincipalRealm::PropertyName() const { \ | 302 | 280 | return PersistentToLocal::Strong(PropertyName##_); \ | 303 | 280 | } \ |
Unexecuted instantiation: node::PrincipalRealm::process_emit_warning_sync() const node::PrincipalRealm::primordials() const Line | Count | Source | 301 | 245 | v8::Local<TypeName> PrincipalRealm::PropertyName() const { \ | 302 | 245 | return PersistentToLocal::Strong(PropertyName##_); \ | 303 | 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 |
304 | 1.33k | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ |
305 | 1.33k | DCHECK_IMPLIES(!value.IsEmpty(), \ |
306 | 1.33k | isolate()->GetCurrentContext() == context()); \ |
307 | 1.33k | PropertyName##_.Reset(isolate(), value); \ |
308 | 1.33k | } node::PrincipalRealm::set_async_hooks_after_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 70 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 70 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 70 | isolate()->GetCurrentContext() == context()); \ | 307 | 70 | PropertyName##_.Reset(isolate(), value); \ | 308 | 70 | } |
node::PrincipalRealm::set_async_hooks_before_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 70 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 70 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 70 | isolate()->GetCurrentContext() == context()); \ | 307 | 70 | PropertyName##_.Reset(isolate(), value); \ | 308 | 70 | } |
node::PrincipalRealm::set_async_hooks_callback_trampoline(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_async_hooks_binding(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_async_hooks_destroy_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 70 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 70 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 70 | isolate()->GetCurrentContext() == context()); \ | 307 | 70 | PropertyName##_.Reset(isolate(), value); \ | 308 | 70 | } |
node::PrincipalRealm::set_async_hooks_init_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 70 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 70 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 70 | isolate()->GetCurrentContext() == context()); \ | 307 | 70 | PropertyName##_.Reset(isolate(), value); \ | 308 | 70 | } |
node::PrincipalRealm::set_async_hooks_promise_resolve_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 70 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 70 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 70 | isolate()->GetCurrentContext() == context()); \ | 307 | 70 | PropertyName##_.Reset(isolate(), value); \ | 308 | 70 | } |
node::PrincipalRealm::set_buffer_prototype_object(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_enhance_fatal_stack_before_inspector(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
Unexecuted instantiation: node::PrincipalRealm::set_host_import_meta_resolve_initializer(v8::Local<v8::Function>) node::PrincipalRealm::set_host_initialize_import_meta_object_callback(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_immediate_callback_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_inspector_console_extension_installer(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_inspector_disable_async_hooks(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_messaging_deserialize_create_object(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_process_object(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_process_emit_warning_sync(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_primordials(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_primordials_safe_map_prototype_object(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_primordials_safe_set_prototype_object(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_primordials_safe_weak_map_prototype_object(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_primordials_safe_weak_set_prototype_object(v8::Local<v8::Object>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_promise_reject_callback(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
node::PrincipalRealm::set_timers_callback_function(v8::Local<v8::Function>) Line | Count | Source | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 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 | 304 | 35 | void PrincipalRealm::set_##PropertyName(v8::Local<TypeName> value) { \ | 305 | 35 | DCHECK_IMPLIES(!value.IsEmpty(), \ | 306 | 35 | isolate()->GetCurrentContext() == context()); \ | 307 | 35 | PropertyName##_.Reset(isolate(), value); \ | 308 | 35 | } |
Unexecuted instantiation: node::PrincipalRealm::set_wasm_streaming_object_constructor(v8::Local<v8::Function>) |
309 | | PER_REALM_STRONG_PERSISTENT_VALUES(V) |
310 | | #undef V |
311 | | |
312 | | PrincipalRealm::PrincipalRealm(Environment* env, |
313 | | v8::Local<v8::Context> context, |
314 | | const RealmSerializeInfo* realm_info) |
315 | 35 | : Realm(env, context, kPrincipal) { |
316 | | // Create properties if not deserializing from snapshot. |
317 | | // Or the properties are deserialized with DeserializeProperties() when the |
318 | | // env drained the deserialize requests. |
319 | 35 | if (realm_info == nullptr) { |
320 | 35 | CreateProperties(); |
321 | 35 | } |
322 | 35 | } |
323 | | |
324 | 35 | PrincipalRealm::~PrincipalRealm() { |
325 | 35 | DCHECK(!context_.IsEmpty()); |
326 | | |
327 | 35 | HandleScope handle_scope(isolate()); |
328 | 35 | env_->UnassignFromContext(context()); |
329 | 35 | } |
330 | | |
331 | 35 | MaybeLocal<Value> PrincipalRealm::BootstrapRealm() { |
332 | 35 | HandleScope scope(isolate_); |
333 | | |
334 | 35 | if (ExecuteBootstrapper("internal/bootstrap/node").IsEmpty()) { |
335 | 0 | return MaybeLocal<Value>(); |
336 | 0 | } |
337 | | |
338 | 35 | if (!env_->no_browser_globals()) { |
339 | 35 | if (ExecuteBootstrapper("internal/bootstrap/web/exposed-wildcard") |
340 | 35 | .IsEmpty() || |
341 | 35 | ExecuteBootstrapper("internal/bootstrap/web/exposed-window-or-worker") |
342 | 35 | .IsEmpty()) { |
343 | 0 | return MaybeLocal<Value>(); |
344 | 0 | } |
345 | 35 | } |
346 | | |
347 | | // TODO(joyeecheung): skip these in the snapshot building for workers. |
348 | 35 | auto thread_switch_id = |
349 | 35 | env_->is_main_thread() ? "internal/bootstrap/switches/is_main_thread" |
350 | 35 | : "internal/bootstrap/switches/is_not_main_thread"; |
351 | 35 | if (ExecuteBootstrapper(thread_switch_id).IsEmpty()) { |
352 | 0 | return MaybeLocal<Value>(); |
353 | 0 | } |
354 | | |
355 | 35 | auto process_state_switch_id = |
356 | 35 | env_->owns_process_state() |
357 | 35 | ? "internal/bootstrap/switches/does_own_process_state" |
358 | 35 | : "internal/bootstrap/switches/does_not_own_process_state"; |
359 | 35 | if (ExecuteBootstrapper(process_state_switch_id).IsEmpty()) { |
360 | 0 | return MaybeLocal<Value>(); |
361 | 0 | } |
362 | | |
363 | | // Setup process.env proxy. |
364 | 35 | Local<String> env_string = FIXED_ONE_BYTE_STRING(isolate_, "env"); |
365 | 35 | Local<Object> env_proxy; |
366 | 35 | if (!isolate_data()->env_proxy_template()->NewInstance(context()).ToLocal( |
367 | 35 | &env_proxy) || |
368 | 35 | process_object()->Set(context(), env_string, env_proxy).IsNothing()) { |
369 | 0 | return MaybeLocal<Value>(); |
370 | 0 | } |
371 | | |
372 | 35 | return v8::True(isolate_); |
373 | 35 | } |
374 | | |
375 | | } // namespace node |