Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/env.h
1 // Copyright Joyent, Inc. and other Node contributors. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a 4 // copy of this software and associated documentation files (the 5 // "Software"), to deal in the Software without restriction, including 6 // without limitation the rights to use, copy, modify, merge, publish, 7 // distribute, sublicense, and/or sell copies of the Software, and to permit 8 // persons to whom the Software is furnished to do so, subject to the 9 // following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included 12 // in all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 #ifndef SRC_ENV_H_ 23 #define SRC_ENV_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "aliased_buffer.h" 28 #if HAVE_INSPECTOR 29 #include "inspector_agent.h" 30 #include "inspector_profiler.h" 31 #endif 32 #include "callback_queue.h" 33 #include "cleanup_queue-inl.h" 34 #include "compile_cache.h" 35 #include "debug_utils.h" 36 #include "env_properties.h" 37 #include "handle_wrap.h" 38 #include "node.h" 39 #include "node_binding.h" 40 #include "node_builtins.h" 41 #include "node_exit_code.h" 42 #include "node_main_instance.h" 43 #include "node_options.h" 44 #include "node_perf_common.h" 45 #include "node_realm.h" 46 #include "node_snapshotable.h" 47 #include "permission/permission.h" 48 #include "req_wrap.h" 49 #include "util.h" 50 #include "uv.h" 51 #include "v8-profiler.h" 52 #include "v8.h" 53 54 #if HAVE_OPENSSL 55 #include <openssl/evp.h> 56 #endif 57 58 #include <array> 59 #include <atomic> 60 #include <cstdint> 61 #include <deque> 62 #include <functional> 63 #include <list> 64 #include <memory> 65 #include <ostream> 66 #include <set> 67 #include <string> 68 #include <unordered_map> 69 #include <unordered_set> 70 #include <vector> 71 72 namespace v8 { 73 class CppHeap; 74 } 75 76 namespace node { 77 78 namespace shadow_realm { 79 class ShadowRealm; 80 } 81 namespace contextify { 82 class ContextifyScript; 83 class CompiledFnEntry; 84 } 85 86 namespace performance { 87 class PerformanceState; 88 } 89 90 namespace tracing { 91 class AgentWriterHandle; 92 } 93 94 #if HAVE_INSPECTOR 95 namespace profiler { 96 class V8CoverageConnection; 97 class V8CpuProfilerConnection; 98 class V8HeapProfilerConnection; 99 } // namespace profiler 100 101 namespace inspector { 102 class ParentInspectorHandle; 103 } 104 #endif // HAVE_INSPECTOR 105 106 namespace worker { 107 class Worker; 108 } 109 110 namespace loader { 111 class ModuleWrap; 112 } // namespace loader 113 114 class Environment; 115 class Realm; 116 117 // Disables zero-filling for ArrayBuffer allocations in this scope. This is 118 // similar to how we implement Buffer.allocUnsafe() in JS land. 119 class NoArrayBufferZeroFillScope { 120 public: 121 inline explicit NoArrayBufferZeroFillScope(IsolateData* isolate_data); 122 inline ~NoArrayBufferZeroFillScope(); 123 124 private: 125 NodeArrayBufferAllocator* node_allocator_; 126 127 friend class Environment; 128 }; 129 130 struct IsolateDataSerializeInfo { 131 std::vector<SnapshotIndex> primitive_values; 132 std::vector<PropInfo> template_values; 133 134 friend std::ostream& operator<<(std::ostream& o, 135 const IsolateDataSerializeInfo& i); 136 }; 137 138 struct PerIsolateWrapperData { 139 uint16_t cppgc_id; 140 uint16_t non_cppgc_id; 141 }; 142 143 class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { 144 private: 145 IsolateData(v8::Isolate* isolate, 146 uv_loop_t* event_loop, 147 MultiIsolatePlatform* platform, 148 ArrayBufferAllocator* node_allocator, 149 const SnapshotData* snapshot_data, 150 std::shared_ptr<PerIsolateOptions> options); 151 152 public: 153 static IsolateData* CreateIsolateData( 154 v8::Isolate* isolate, 155 uv_loop_t* event_loop, 156 MultiIsolatePlatform* platform = nullptr, 157 ArrayBufferAllocator* node_allocator = nullptr, 158 const EmbedderSnapshotData* embedder_snapshot_data = nullptr, 159 std::shared_ptr<PerIsolateOptions> options = nullptr); 160 ~IsolateData(); 161 162 SET_MEMORY_INFO_NAME(IsolateData) 163 SET_SELF_SIZE(IsolateData) 164 void MemoryInfo(MemoryTracker* tracker) const override; 165 IsolateDataSerializeInfo Serialize(v8::SnapshotCreator* creator); 166 167 bool is_building_snapshot() const { return snapshot_config_.has_value(); } 168 const SnapshotConfig* snapshot_config() const { 169 return snapshot_config_.has_value() ? &(snapshot_config_.value()) : nullptr; 170 } 171 void set_snapshot_config(const SnapshotConfig* config) { 172 if (config != nullptr) { 173 snapshot_config_ = *config; // Copy the config. 174 } 175 } 176 177 uint16_t* embedder_id_for_cppgc() const; 178 uint16_t* embedder_id_for_non_cppgc() const; 179 180 static inline void SetCppgcReference(v8::Isolate* isolate, 181 v8::Local<v8::Object> object, 182 void* wrappable); 183 184 inline uv_loop_t* event_loop() const; 185 inline MultiIsolatePlatform* platform() const; 186 inline const SnapshotData* snapshot_data() const; 187 inline std::shared_ptr<PerIsolateOptions> options(); 188 189 inline NodeArrayBufferAllocator* node_allocator() const; 190 191 inline worker::Worker* worker_context() const; 192 inline void set_worker_context(worker::Worker* context); 193 194 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 195 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 196 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 197 #define VR(PropertyName, TypeName) V(v8::Private, per_realm_##PropertyName) 198 #define V(TypeName, PropertyName) \ 199 inline v8::Local<TypeName> PropertyName() const; 200 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 201 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 202 PER_ISOLATE_STRING_PROPERTIES(VS) 203 PER_REALM_STRONG_PERSISTENT_VALUES(VR) 204 #undef V 205 #undef VR 206 #undef VY 207 #undef VS 208 #undef VP 209 210 #define VM(PropertyName) V(PropertyName##_binding_template, v8::ObjectTemplate) 211 #define V(PropertyName, TypeName) \ 212 inline v8::Local<TypeName> PropertyName() const; \ 213 inline void set_##PropertyName(v8::Local<TypeName> value); 214 PER_ISOLATE_TEMPLATE_PROPERTIES(V) 215 NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) 216 #undef V 217 #undef VM 218 219 inline v8::Local<v8::String> async_wrap_provider(int index) const; 220 221 size_t max_young_gen_size = 1; 222 std::unordered_map<const char*, v8::Eternal<v8::String>> static_str_map; 223 224 inline v8::Isolate* isolate() const; 225 IsolateData(const IsolateData&) = delete; 226 IsolateData& operator=(const IsolateData&) = delete; 227 IsolateData(IsolateData&&) = delete; 228 IsolateData& operator=(IsolateData&&) = delete; 229 230 private: 231 void DeserializeProperties(const IsolateDataSerializeInfo* isolate_data_info); 232 void CreateProperties(); 233 234 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 235 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 236 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 237 #define VR(PropertyName, TypeName) V(v8::Private, per_realm_##PropertyName) 238 #define VM(PropertyName) V(v8::ObjectTemplate, PropertyName##_binding_template) 239 #define VT(PropertyName, TypeName) V(TypeName, PropertyName) 240 #define V(TypeName, PropertyName) \ 241 v8::Eternal<TypeName> PropertyName ## _; 242 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 243 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 244 PER_ISOLATE_STRING_PROPERTIES(VS) 245 PER_ISOLATE_TEMPLATE_PROPERTIES(VT) 246 PER_REALM_STRONG_PERSISTENT_VALUES(VR) 247 NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) 248 #undef V 249 #undef VM 250 #undef VR 251 #undef VT 252 #undef VS 253 #undef VY 254 #undef VP 255 // Keep a list of all Persistent strings used for AsyncWrap Provider types. 256 std::array<v8::Eternal<v8::String>, AsyncWrap::PROVIDERS_LENGTH> 257 async_wrap_providers_; 258 259 v8::Isolate* const isolate_; 260 uv_loop_t* const event_loop_; 261 NodeArrayBufferAllocator* const node_allocator_; 262 MultiIsolatePlatform* platform_; 263 264 const SnapshotData* snapshot_data_; 265 std::optional<SnapshotConfig> snapshot_config_; 266 267 std::unique_ptr<v8::CppHeap> cpp_heap_; 268 std::shared_ptr<PerIsolateOptions> options_; 269 worker::Worker* worker_context_ = nullptr; 270 PerIsolateWrapperData* wrapper_data_; 271 272 static Mutex isolate_data_mutex_; 273 static std::unordered_map<uint16_t, std::unique_ptr<PerIsolateWrapperData>> 274 wrapper_data_map_; 275 }; 276 277 struct ContextInfo { 278 explicit ContextInfo(const std::string& name) : name(name) {} 279 const std::string name; 280 std::string origin; 281 bool is_default = false; 282 }; 283 284 class EnabledDebugList; 285 286 namespace per_process { 287 extern std::shared_ptr<KVStore> system_environment; 288 } 289 290 struct EnvSerializeInfo; 291 292 class AsyncHooks : public MemoryRetainer { 293 public: 294 SET_MEMORY_INFO_NAME(AsyncHooks) 295 SET_SELF_SIZE(AsyncHooks) 296 void MemoryInfo(MemoryTracker* tracker) const override; 297 298 // Reason for both UidFields and Fields are that one is stored as a double* 299 // and the other as a uint32_t*. 300 enum Fields { 301 kInit, 302 kBefore, 303 kAfter, 304 kDestroy, 305 kPromiseResolve, 306 kTotals, 307 kCheck, 308 kStackLength, 309 kUsesExecutionAsyncResource, 310 kFieldsCount, 311 }; 312 313 enum UidFields { 314 kExecutionAsyncId, 315 kTriggerAsyncId, 316 kAsyncIdCounter, 317 kDefaultTriggerAsyncId, 318 kUidFieldsCount, 319 }; 320 321 inline AliasedUint32Array& fields(); 322 inline AliasedFloat64Array& async_id_fields(); 323 inline AliasedFloat64Array& async_ids_stack(); 324 inline v8::Local<v8::Array> js_execution_async_resources(); 325 // Returns the native executionAsyncResource value at stack index `index`. 326 // Resources provided on the JS side are not stored on the native stack, 327 // in which case an empty `Local<>` is returned. 328 // The `js_execution_async_resources` array contains the value in that case. 329 inline v8::Local<v8::Object> native_execution_async_resource(size_t index); 330 331 void InstallPromiseHooks(v8::Local<v8::Context> ctx); 332 void ResetPromiseHooks(v8::Local<v8::Function> init, 333 v8::Local<v8::Function> before, 334 v8::Local<v8::Function> after, 335 v8::Local<v8::Function> resolve); 336 // Used for testing since V8 doesn't provide API for retrieving configured 337 // JS promise hooks. 338 v8::Local<v8::Array> GetPromiseHooks(v8::Isolate* isolate) const; 339 inline v8::Local<v8::String> provider_string(int idx); 340 341 inline void no_force_checks(); 342 inline Environment* env(); 343 344 // NB: This call does not take (co-)ownership of `execution_async_resource`. 345 // The lifetime of the `v8::Local<>` pointee must last until 346 // `pop_async_context()` or `clear_async_id_stack()` are called. 347 void push_async_context(double async_id, 348 double trigger_async_id, 349 v8::Local<v8::Object>* execution_async_resource); 350 bool pop_async_context(double async_id); 351 void clear_async_id_stack(); // Used in fatal exceptions. 352 353 AsyncHooks(const AsyncHooks&) = delete; 354 AsyncHooks& operator=(const AsyncHooks&) = delete; 355 AsyncHooks(AsyncHooks&&) = delete; 356 AsyncHooks& operator=(AsyncHooks&&) = delete; 357 ~AsyncHooks() = default; 358 359 // Used to set the kDefaultTriggerAsyncId in a scope. This is instead of 360 // passing the trigger_async_id along with other constructor arguments. 361 class DefaultTriggerAsyncIdScope { 362 public: 363 DefaultTriggerAsyncIdScope() = delete; 364 explicit DefaultTriggerAsyncIdScope(Environment* env, 365 double init_trigger_async_id); 366 explicit DefaultTriggerAsyncIdScope(AsyncWrap* async_wrap); 367 ~DefaultTriggerAsyncIdScope(); 368 369 DefaultTriggerAsyncIdScope(const DefaultTriggerAsyncIdScope&) = delete; 370 DefaultTriggerAsyncIdScope& operator=(const DefaultTriggerAsyncIdScope&) = 371 delete; 372 DefaultTriggerAsyncIdScope(DefaultTriggerAsyncIdScope&&) = delete; 373 DefaultTriggerAsyncIdScope& operator=(DefaultTriggerAsyncIdScope&&) = 374 delete; 375 376 private: 377 AsyncHooks* async_hooks_; 378 double old_default_trigger_async_id_; 379 }; 380 381 struct SerializeInfo { 382 AliasedBufferIndex async_ids_stack; 383 AliasedBufferIndex fields; 384 AliasedBufferIndex async_id_fields; 385 SnapshotIndex js_execution_async_resources; 386 std::vector<SnapshotIndex> native_execution_async_resources; 387 }; 388 389 SerializeInfo Serialize(v8::Local<v8::Context> context, 390 v8::SnapshotCreator* creator); 391 void Deserialize(v8::Local<v8::Context> context); 392 393 private: 394 friend class Environment; // So we can call the constructor. 395 explicit AsyncHooks(v8::Isolate* isolate, const SerializeInfo* info); 396 397 [[noreturn]] void FailWithCorruptedAsyncStack(double expected_async_id); 398 399 // Stores the ids of the current execution context stack. 400 AliasedFloat64Array async_ids_stack_; 401 // Attached to a Uint32Array that tracks the number of active hooks for 402 // each type. 403 AliasedUint32Array fields_; 404 // Attached to a Float64Array that tracks the state of async resources. 405 AliasedFloat64Array async_id_fields_; 406 407 void grow_async_ids_stack(); 408 409 v8::Global<v8::Array> js_execution_async_resources_; 410 411 // We avoid storing the handles directly here, because they are already 412 // properly allocated on the stack, we just need access to them here. 413 std::deque<v8::Local<v8::Object>*> native_execution_async_resources_; 414 415 // Non-empty during deserialization 416 const SerializeInfo* info_ = nullptr; 417 418 std::array<v8::Global<v8::Function>, 4> js_promise_hooks_; 419 }; 420 421 class ImmediateInfo : public MemoryRetainer { 422 public: 423 inline AliasedUint32Array& fields(); 424 inline uint32_t count() const; 425 inline uint32_t ref_count() const; 426 inline bool has_outstanding() const; 427 inline void ref_count_inc(uint32_t increment); 428 inline void ref_count_dec(uint32_t decrement); 429 430 ImmediateInfo(const ImmediateInfo&) = delete; 431 ImmediateInfo& operator=(const ImmediateInfo&) = delete; 432 ImmediateInfo(ImmediateInfo&&) = delete; 433 ImmediateInfo& operator=(ImmediateInfo&&) = delete; 434 ~ImmediateInfo() = default; 435 436 SET_MEMORY_INFO_NAME(ImmediateInfo) 437 SET_SELF_SIZE(ImmediateInfo) 438 void MemoryInfo(MemoryTracker* tracker) const override; 439 440 struct SerializeInfo { 441 AliasedBufferIndex fields; 442 }; 443 SerializeInfo Serialize(v8::Local<v8::Context> context, 444 v8::SnapshotCreator* creator); 445 void Deserialize(v8::Local<v8::Context> context); 446 447 private: 448 friend class Environment; // So we can call the constructor. 449 explicit ImmediateInfo(v8::Isolate* isolate, const SerializeInfo* info); 450 451 enum Fields { kCount, kRefCount, kHasOutstanding, kFieldsCount }; 452 453 AliasedUint32Array fields_; 454 }; 455 456 class TickInfo : public MemoryRetainer { 457 public: 458 inline AliasedUint8Array& fields(); 459 inline bool has_tick_scheduled() const; 460 inline bool has_rejection_to_warn() const; 461 462 SET_MEMORY_INFO_NAME(TickInfo) 463 SET_SELF_SIZE(TickInfo) 464 void MemoryInfo(MemoryTracker* tracker) const override; 465 466 TickInfo(const TickInfo&) = delete; 467 TickInfo& operator=(const TickInfo&) = delete; 468 TickInfo(TickInfo&&) = delete; 469 TickInfo& operator=(TickInfo&&) = delete; 470 ~TickInfo() = default; 471 472 struct SerializeInfo { 473 AliasedBufferIndex fields; 474 }; 475 SerializeInfo Serialize(v8::Local<v8::Context> context, 476 v8::SnapshotCreator* creator); 477 void Deserialize(v8::Local<v8::Context> context); 478 479 private: 480 friend class Environment; // So we can call the constructor. 481 explicit TickInfo(v8::Isolate* isolate, const SerializeInfo* info); 482 483 enum Fields { kHasTickScheduled = 0, kHasRejectionToWarn, kFieldsCount }; 484 485 AliasedUint8Array fields_; 486 }; 487 488 class TrackingTraceStateObserver : 489 public v8::TracingController::TraceStateObserver { 490 public: 491 explicit TrackingTraceStateObserver(Environment* env) : env_(env) {} 492 493 void OnTraceEnabled() override { 494 UpdateTraceCategoryState(); 495 } 496 497 void OnTraceDisabled() override { 498 UpdateTraceCategoryState(); 499 } 500 501 private: 502 void UpdateTraceCategoryState(); 503 504 Environment* env_; 505 }; 506 507 class ShouldNotAbortOnUncaughtScope { 508 public: 509 explicit inline ShouldNotAbortOnUncaughtScope(Environment* env); 510 inline void Close(); 511 inline ~ShouldNotAbortOnUncaughtScope(); 512 ShouldNotAbortOnUncaughtScope(const ShouldNotAbortOnUncaughtScope&) = delete; 513 ShouldNotAbortOnUncaughtScope& operator=( 514 const ShouldNotAbortOnUncaughtScope&) = delete; 515 ShouldNotAbortOnUncaughtScope(ShouldNotAbortOnUncaughtScope&&) = delete; 516 ShouldNotAbortOnUncaughtScope& operator=(ShouldNotAbortOnUncaughtScope&&) = 517 delete; 518 519 private: 520 Environment* env_; 521 }; 522 523 typedef void (*DeserializeRequestCallback)(v8::Local<v8::Context> context, 524 v8::Local<v8::Object> holder, 525 int index, 526 InternalFieldInfoBase* info); 527 struct DeserializeRequest { 528 DeserializeRequestCallback cb; 529 v8::Global<v8::Object> holder; 530 int index; 531 InternalFieldInfoBase* info = nullptr; // Owned by the request 532 }; 533 534 struct EnvSerializeInfo { 535 AsyncHooks::SerializeInfo async_hooks; 536 TickInfo::SerializeInfo tick_info; 537 ImmediateInfo::SerializeInfo immediate_info; 538 AliasedBufferIndex timeout_info; 539 performance::PerformanceState::SerializeInfo performance_state; 540 AliasedBufferIndex exit_info; 541 AliasedBufferIndex stream_base_state; 542 AliasedBufferIndex should_abort_on_uncaught_toggle; 543 544 RealmSerializeInfo principal_realm; 545 friend std::ostream& operator<<(std::ostream& o, const EnvSerializeInfo& i); 546 }; 547 548 struct SnapshotMetadata { 549 // For now kFullyCustomized is only built with the --build-snapshot CLI flag. 550 // We might want to add more types of snapshots in the future. 551 enum class Type : uint8_t { kDefault, kFullyCustomized }; 552 553 Type type; 554 std::string node_version; 555 std::string node_arch; 556 std::string node_platform; 557 SnapshotFlags flags; 558 }; 559 560 struct SnapshotData { 561 enum class DataOwnership { kOwned, kNotOwned }; 562 563 static const uint32_t kMagic = 0x143da19; 564 static const SnapshotIndex kNodeVMContextIndex = 0; 565 static const SnapshotIndex kNodeBaseContextIndex = kNodeVMContextIndex + 1; 566 static const SnapshotIndex kNodeMainContextIndex = kNodeBaseContextIndex + 1; 567 568 DataOwnership data_ownership = DataOwnership::kOwned; 569 570 SnapshotMetadata metadata; 571 572 // The result of v8::SnapshotCreator::CreateBlob() during the snapshot 573 // building process. 574 v8::StartupData v8_snapshot_blob_data{nullptr, 0}; 575 576 IsolateDataSerializeInfo isolate_data_info; 577 // TODO(joyeecheung): there should be a vector of env_info once we snapshot 578 // the worker environments. 579 EnvSerializeInfo env_info; 580 581 // A vector of built-in ids and v8::ScriptCompiler::CachedData, this can be 582 // shared across Node.js instances because they are supposed to share the 583 // read only space. We use builtins::CodeCacheInfo because 584 // v8::ScriptCompiler::CachedData is not copyable. 585 std::vector<builtins::CodeCacheInfo> code_cache; 586 587 void ToFile(FILE* out) const; 588 std::vector<char> ToBlob() const; 589 // If returns false, the metadata doesn't match the current Node.js binary, 590 // and the caller should not consume the snapshot data. 591 bool Check() const; 592 static bool FromFile(SnapshotData* out, FILE* in); 593 static bool FromBlob(SnapshotData* out, const std::vector<char>& in); 594 static bool FromBlob(SnapshotData* out, std::string_view in); 595 static const SnapshotData* FromEmbedderWrapper( 596 const EmbedderSnapshotData* data); 597 EmbedderSnapshotData::Pointer AsEmbedderWrapper() const; 598 599 ~SnapshotData(); 600 }; 601 602 void DefaultProcessExitHandlerInternal(Environment* env, ExitCode exit_code); 603 v8::Maybe<ExitCode> SpinEventLoopInternal(Environment* env); 604 v8::Maybe<ExitCode> EmitProcessExitInternal(Environment* env); 605 606 class Cleanable { 607 public: 608 virtual ~Cleanable() = default; 609 610 protected: 611 ListNode<Cleanable> cleanable_queue_; 612 613 private: 614 virtual void Clean() = 0; 615 friend class Environment; 616 }; 617 618 /** 619 * Environment is a per-isolate data structure that represents an execution 620 * environment. Each environment has a principal realm. An environment can 621 * create multiple subsidiary synthetic realms. 622 */ 623 class Environment final : public MemoryRetainer { 624 public: 625 Environment(const Environment&) = delete; 626 Environment& operator=(const Environment&) = delete; 627 Environment(Environment&&) = delete; 628 Environment& operator=(Environment&&) = delete; 629 630 SET_MEMORY_INFO_NAME(Environment) 631 632 static std::string GetExecPath(const std::vector<std::string>& argv); 633 static std::string GetCwd(const std::string& exec_path); 634 635 inline size_t SelfSize() const override; 636 bool IsRootNode() const override { return true; } 637 void MemoryInfo(MemoryTracker* tracker) const override; 638 639 EnvSerializeInfo Serialize(v8::SnapshotCreator* creator); 640 void DeserializeProperties(const EnvSerializeInfo* info); 641 642 void PrintInfoForSnapshotIfDebug(); 643 void EnqueueDeserializeRequest(DeserializeRequestCallback cb, 644 v8::Local<v8::Object> holder, 645 int index, 646 InternalFieldInfoBase* info); 647 void RunDeserializeRequests(); 648 // Should be called before InitializeInspector() 649 void InitializeDiagnostics(); 650 651 #if HAVE_INSPECTOR 652 // If the environment is created for a worker, pass parent_handle and 653 // the ownership if transferred into the Environment. 654 void InitializeInspector( 655 std::unique_ptr<inspector::ParentInspectorHandle> parent_handle); 656 void WaitForInspectorFrontendByOptions(); 657 #endif 658 659 inline size_t async_callback_scope_depth() const; 660 inline void PushAsyncCallbackScope(); 661 inline void PopAsyncCallbackScope(); 662 663 static inline Environment* GetCurrent(v8::Isolate* isolate); 664 static inline Environment* GetCurrent(v8::Local<v8::Context> context); 665 static inline Environment* GetCurrent( 666 const v8::FunctionCallbackInfo<v8::Value>& info); 667 668 template <typename T> 669 static inline Environment* GetCurrent( 670 const v8::PropertyCallbackInfo<T>& info); 671 672 // Create an Environment without initializing a main Context. Use 673 // InitializeMainContext() to initialize a main context for it. 674 Environment(IsolateData* isolate_data, 675 v8::Isolate* isolate, 676 const std::vector<std::string>& args, 677 const std::vector<std::string>& exec_args, 678 const EnvSerializeInfo* env_info, 679 EnvironmentFlags::Flags flags, 680 ThreadId thread_id, 681 std::string_view thread_name = ""); 682 void InitializeMainContext(v8::Local<v8::Context> context, 683 const EnvSerializeInfo* env_info); 684 ~Environment() override; 685 686 void InitializeLibuv(); 687 inline const std::vector<std::string>& exec_argv(); 688 inline const std::vector<std::string>& argv(); 689 const std::string& exec_path() const; 690 691 void CleanupHandles(); 692 void Exit(ExitCode code); 693 void ExitEnv(StopFlags::Flags flags); 694 void ClosePerEnvHandles(); 695 696 template <typename T, typename OnCloseCallback> 697 inline void CloseHandle(T* handle, OnCloseCallback callback); 698 699 void ResetPromiseHooks(v8::Local<v8::Function> init, 700 v8::Local<v8::Function> before, 701 v8::Local<v8::Function> after, 702 v8::Local<v8::Function> resolve); 703 void AssignToContext(v8::Local<v8::Context> context, 704 Realm* realm, 705 const ContextInfo& info); 706 void UnassignFromContext(v8::Local<v8::Context> context); 707 void TrackShadowRealm(shadow_realm::ShadowRealm* realm); 708 void UntrackShadowRealm(shadow_realm::ShadowRealm* realm); 709 710 void StartProfilerIdleNotifier(); 711 712 inline v8::Isolate* isolate() const; 713 inline uv_loop_t* event_loop() const; 714 void TryLoadAddon(const char* filename, 715 int flags, 716 const std::function<bool(binding::DLib*)>& was_loaded); 717 718 static inline Environment* from_timer_handle(uv_timer_t* handle); 719 inline uv_timer_t* timer_handle(); 720 721 static inline Environment* from_immediate_check_handle(uv_check_t* handle); 722 inline uv_check_t* immediate_check_handle(); 723 inline uv_idle_t* immediate_idle_handle(); 724 725 inline void IncreaseWaitingRequestCounter(); 726 inline void DecreaseWaitingRequestCounter(); 727 728 inline AsyncHooks* async_hooks(); 729 inline ImmediateInfo* immediate_info(); 730 inline AliasedInt32Array& timeout_info(); 731 inline TickInfo* tick_info(); 732 inline uint64_t timer_base() const; 733 inline permission::Permission* permission(); 734 inline std::shared_ptr<KVStore> env_vars(); 735 inline void set_env_vars(std::shared_ptr<KVStore> env_vars); 736 737 inline IsolateData* isolate_data() const; 738 739 inline bool printed_error() const; 740 inline void set_printed_error(bool value); 741 742 void PrintSyncTrace() const; 743 inline void set_trace_sync_io(bool value); 744 745 inline void set_force_context_aware(bool value); 746 inline bool force_context_aware() const; 747 748 // This contains fields that are a pseudo-boolean that keeps track of whether 749 // the process is exiting, an integer representing the process exit code, and 750 // a pseudo-boolean to indicate whether the exit code is undefined. 751 inline AliasedInt32Array& exit_info(); 752 inline void set_exiting(bool value); 753 bool exiting() const; 754 inline ExitCode exit_code(const ExitCode default_code) const; 755 756 inline void set_exit_code(const ExitCode code); 757 758 // This stores whether the --abort-on-uncaught-exception flag was passed 759 // to Node. 760 inline bool abort_on_uncaught_exception() const; 761 inline void set_abort_on_uncaught_exception(bool value); 762 // This is a pseudo-boolean that keeps track of whether an uncaught exception 763 // should abort the process or not if --abort-on-uncaught-exception was 764 // passed to Node. If the flag was not passed, it is ignored. 765 inline AliasedUint32Array& should_abort_on_uncaught_toggle(); 766 767 inline AliasedInt32Array& stream_base_state(); 768 769 // The necessary API for async_hooks. 770 inline double new_async_id(); 771 inline double execution_async_id(); 772 inline double trigger_async_id(); 773 inline double get_default_trigger_async_id(); 774 775 // List of id's that have been destroyed and need the destroy() cb called. 776 inline std::vector<double>* destroy_async_id_list(); 777 778 builtins::BuiltinLoader* builtin_loader(); 779 780 std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map; 781 782 EnabledDebugList* enabled_debug_list() { return &enabled_debug_list_; } 783 784 inline performance::PerformanceState* performance_state(); 785 786 v8::Maybe<void> CollectUVExceptionInfo(v8::Local<v8::Value> context, 787 int errorno, 788 const char* syscall = nullptr, 789 const char* message = nullptr, 790 const char* path = nullptr, 791 const char* dest = nullptr); 792 793 // If this flag is set, calls into JS (if they would be observable 794 // from userland) must be avoided. This flag does not indicate whether 795 // calling into JS is allowed from a VM perspective at this point. 796 inline bool can_call_into_js() const; 797 inline void set_can_call_into_js(bool can_call_into_js); 798 799 // Increase or decrease a counter that manages whether this Environment 800 // keeps the event loop alive on its own or not. The counter starts out at 0, 801 // meaning it does not, and any positive value will make it keep the event 802 // loop alive. 803 // This is used by Workers to manage their own .ref()/.unref() implementation, 804 // as Workers aren't directly associated with their own libuv handles. 805 void add_refs(int64_t diff); 806 807 // Convenient getter of the principal realm's has_run_bootstrapping_code(). 808 inline bool has_run_bootstrapping_code() const; 809 810 inline bool has_serialized_options() const; 811 inline void set_has_serialized_options(bool has_serialized_options); 812 813 inline bool is_main_thread() const; 814 inline bool no_native_addons() const; 815 inline bool should_not_register_esm_loader() const; 816 inline bool should_create_inspector() const; 817 inline bool should_wait_for_inspector_frontend() const; 818 inline bool owns_process_state() const; 819 inline bool owns_inspector() const; 820 inline bool tracks_unmanaged_fds() const; 821 inline bool hide_console_windows() const; 822 inline bool no_global_search_paths() const; 823 inline bool should_start_debug_signal_handler() const; 824 inline bool no_browser_globals() const; 825 inline uint64_t thread_id() const; 826 inline std::string_view thread_name() const; 827 inline worker::Worker* worker_context() const; 828 Environment* worker_parent_env() const; 829 inline void add_sub_worker_context(worker::Worker* context); 830 inline void remove_sub_worker_context(worker::Worker* context); 831 void stop_sub_worker_contexts(); 832 template <typename Fn> 833 inline void ForEachWorker(Fn&& iterator); 834 // Determine if the environment is stopping. This getter is thread-safe. 835 inline bool is_stopping() const; 836 inline void set_stopping(bool value); 837 inline std::list<node_module>* extra_linked_bindings(); 838 inline node_module* extra_linked_bindings_head(); 839 inline node_module* extra_linked_bindings_tail(); 840 inline const Mutex& extra_linked_bindings_mutex() const; 841 842 inline bool filehandle_close_warning() const; 843 inline void set_filehandle_close_warning(bool on); 844 845 inline void set_source_maps_enabled(bool on); 846 inline bool source_maps_enabled() const; 847 848 inline void ThrowError(const char* errmsg); 849 inline void ThrowTypeError(const char* errmsg); 850 inline void ThrowRangeError(const char* errmsg); 851 inline void ThrowStdErrException(std::error_code error_code, 852 const char* syscall, 853 const char* path = nullptr); 854 inline void ThrowErrnoException(int errorno, 855 const char* syscall = nullptr, 856 const char* message = nullptr, 857 const char* path = nullptr); 858 inline void ThrowUVException(int errorno, 859 const char* syscall = nullptr, 860 const char* message = nullptr, 861 const char* path = nullptr, 862 const char* dest = nullptr); 863 864 void AtExit(void (*cb)(void* arg), void* arg); 865 void RunAtExitCallbacks(); 866 867 v8::Maybe<bool> CheckUnsettledTopLevelAwait() const; 868 void RunWeakRefCleanup(); 869 870 v8::MaybeLocal<v8::Value> RunSnapshotSerializeCallback() const; 871 v8::MaybeLocal<v8::Value> RunSnapshotDeserializeCallback() const; 872 v8::MaybeLocal<v8::Value> RunSnapshotDeserializeMain() const; 873 874 // Primitive values are shared across realms. 875 // The getters simply proxy to the per-isolate primitive. 876 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 877 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 878 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 879 #define V(TypeName, PropertyName) \ 880 inline v8::Local<TypeName> PropertyName() const; 881 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 882 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 883 PER_ISOLATE_STRING_PROPERTIES(VS) 884 #undef V 885 #undef VS 886 #undef VY 887 #undef VP 888 889 #define V(PropertyName, TypeName) \ 890 inline v8::Local<TypeName> PropertyName() const; \ 891 inline void set_ ## PropertyName(v8::Local<TypeName> value); 892 PER_ISOLATE_TEMPLATE_PROPERTIES(V) 893 // Per-realm strong persistent values of the principal realm. 894 // Get/set the value with an explicit realm instead when possible. 895 // Deprecate soon. 896 PER_REALM_STRONG_PERSISTENT_VALUES(V) 897 #undef V 898 899 // Return the context of the principal realm. 900 // Get the context with an explicit realm instead when possible. 901 // Deprecate soon. 902 inline v8::Local<v8::Context> context() const; 903 inline PrincipalRealm* principal_realm() const; 904 905 #if HAVE_INSPECTOR 906 inline inspector::Agent* inspector_agent() const { 907 return inspector_agent_.get(); 908 } 909 inline void StopInspector() { 910 inspector_agent_.reset(); 911 } 912 913 inline bool is_in_inspector_console_call() const; 914 inline void set_is_in_inspector_console_call(bool value); 915 #endif 916 917 typedef ListHead<HandleWrap, &HandleWrap::handle_wrap_queue_> HandleWrapQueue; 918 typedef ListHead<ReqWrapBase, &ReqWrapBase::req_wrap_queue_> ReqWrapQueue; 919 typedef ListHead<Cleanable, &Cleanable::cleanable_queue_> CleanableQueue; 920 921 inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } 922 inline CleanableQueue* cleanable_queue() { 923 return &cleanable_queue_; 924 } 925 inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } 926 927 // https://w3c.github.io/hr-time/#dfn-time-origin 928 inline uint64_t time_origin() { 929 return time_origin_; 930 } 931 // https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp 932 inline double time_origin_timestamp() { 933 return time_origin_timestamp_; 934 } 935 936 inline bool EmitProcessEnvWarning() { 937 bool current_value = emit_env_nonstring_warning_; 938 emit_env_nonstring_warning_ = false; 939 return current_value; 940 } 941 942 inline bool EmitErrNameWarning() { 943 bool current_value = emit_err_name_warning_; 944 emit_err_name_warning_ = false; 945 return current_value; 946 } 947 948 // cb will be called as cb(env) on the next event loop iteration. 949 // Unlike the JS setImmediate() function, nested SetImmediate() calls will 950 // be run without returning control to the event loop, similar to nextTick(). 951 template <typename Fn> 952 inline void SetImmediate( 953 Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed); 954 template <typename Fn> 955 // This behaves like SetImmediate() but can be called from any thread. 956 inline void SetImmediateThreadsafe( 957 Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed); 958 // This behaves like V8's Isolate::RequestInterrupt(), but also accounts for 959 // the event loop (i.e. combines the V8 function with SetImmediate()). 960 // The passed callback may not throw exceptions. 961 // This function can be called from any thread. 962 template <typename Fn> 963 inline void RequestInterrupt(Fn&& cb); 964 // This needs to be available for the JS-land setImmediate(). 965 void ToggleImmediateRef(bool ref); 966 967 inline void PushShouldNotAbortOnUncaughtScope(); 968 inline void PopShouldNotAbortOnUncaughtScope(); 969 inline bool inside_should_not_abort_on_uncaught_scope() const; 970 971 static inline Environment* ForAsyncHooks(AsyncHooks* hooks); 972 973 v8::Local<v8::Value> GetNow(); 974 uint64_t GetNowUint64(); 975 976 void ScheduleTimer(int64_t duration); 977 void ToggleTimerRef(bool ref); 978 979 inline void AddCleanupHook(CleanupQueue::Callback cb, void* arg); 980 inline void RemoveCleanupHook(CleanupQueue::Callback cb, void* arg); 981 void RunCleanup(); 982 983 static void TracePromises(v8::PromiseHookType type, 984 v8::Local<v8::Promise> promise, 985 v8::Local<v8::Value> parent); 986 static size_t NearHeapLimitCallback(void* data, 987 size_t current_heap_limit, 988 size_t initial_heap_limit); 989 static void BuildEmbedderGraph(v8::Isolate* isolate, 990 v8::EmbedderGraph* graph, 991 void* data); 992 993 inline std::shared_ptr<EnvironmentOptions> options(); 994 inline std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port(); 995 996 inline int64_t stack_trace_limit() const; 997 998 #if HAVE_INSPECTOR 999 void set_coverage_connection( 1000 std::unique_ptr<profiler::V8CoverageConnection> connection); 1001 profiler::V8CoverageConnection* coverage_connection(); 1002 1003 inline void set_coverage_directory(const char* directory); 1004 inline const std::string& coverage_directory() const; 1005 1006 void set_cpu_profiler_connection( 1007 std::unique_ptr<profiler::V8CpuProfilerConnection> connection); 1008 profiler::V8CpuProfilerConnection* cpu_profiler_connection(); 1009 1010 inline void set_cpu_prof_name(const std::string& name); 1011 inline const std::string& cpu_prof_name() const; 1012 1013 inline void set_cpu_prof_interval(uint64_t interval); 1014 inline uint64_t cpu_prof_interval() const; 1015 1016 inline void set_cpu_prof_dir(const std::string& dir); 1017 inline const std::string& cpu_prof_dir() const; 1018 1019 void set_heap_profiler_connection( 1020 std::unique_ptr<profiler::V8HeapProfilerConnection> connection); 1021 profiler::V8HeapProfilerConnection* heap_profiler_connection(); 1022 1023 inline void set_heap_prof_name(const std::string& name); 1024 inline const std::string& heap_prof_name() const; 1025 1026 inline void set_heap_prof_dir(const std::string& dir); 1027 inline const std::string& heap_prof_dir() const; 1028 1029 inline void set_heap_prof_interval(uint64_t interval); 1030 inline uint64_t heap_prof_interval() const; 1031 1032 #endif // HAVE_INSPECTOR 1033 1034 inline const EmbedderPreloadCallback& embedder_preload() const; 1035 inline void set_embedder_preload(EmbedderPreloadCallback fn); 1036 1037 inline void set_process_exit_handler( 1038 std::function<void(Environment*, ExitCode)>&& handler); 1039 1040 inline CompileCacheHandler* compile_cache_handler(); 1041 inline bool use_compile_cache() const; 1042 void InitializeCompileCache(); 1043 // Enable built-in compile cache if it has not yet been enabled. 1044 // The cache will be persisted to disk on exit. 1045 CompileCacheEnableResult EnableCompileCache(const std::string& cache_dir); 1046 void FlushCompileCache(); 1047 1048 void RunAndClearNativeImmediates(bool only_refed = false); 1049 void RunAndClearInterrupts(); 1050 1051 uv_buf_t allocate_managed_buffer(const size_t suggested_size); 1052 std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf); 1053 1054 void AddUnmanagedFd(int fd); 1055 void RemoveUnmanagedFd(int fd); 1056 1057 template <typename T> 1058 void ForEachRealm(T&& iterator) const; 1059 1060 inline void set_heap_snapshot_near_heap_limit(uint32_t limit); 1061 inline bool is_in_heapsnapshot_heap_limit_callback() const; 1062 1063 inline bool report_exclude_env() const; 1064 1065 inline void AddHeapSnapshotNearHeapLimitCallback(); 1066 1067 inline void RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit); 1068 1069 v8::CpuProfilingResult StartCpuProfile(std::string_view name); 1070 v8::CpuProfile* StopCpuProfile(std::string_view name); 1071 1072 // Field identifiers for exit_info_ 1073 enum ExitInfoField { 1074 kExiting = 0, 1075 kExitCode, 1076 kHasExitCode, 1077 kExitInfoFieldCount 1078 }; 1079 1080 #if HAVE_OPENSSL 1081 #if OPENSSL_VERSION_MAJOR >= 3 1082 // We declare another alias here to avoid having to include crypto_util.h 1083 using EVPMDPointer = DeleteFnPtr<EVP_MD, EVP_MD_free>; 1084 std::vector<EVPMDPointer> evp_md_cache; 1085 #endif // OPENSSL_VERSION_MAJOR >= 3 1086 std::unordered_map<std::string, size_t> alias_to_md_id_map; 1087 std::vector<std::string> supported_hash_algorithms; 1088 #endif // HAVE_OPENSSL 1089 1090 v8::Global<v8::Module> temporary_required_module_facade_original; 1091 1092 void SetAsyncResourceContextFrame(std::uintptr_t async_resource_handle, 1093 v8::Global<v8::Value>&&); 1094 1095 const v8::Global<v8::Value>& GetAsyncResourceContextFrame( 1096 std::uintptr_t async_resource_handle); 1097 1098 void RemoveAsyncResourceContextFrame(std::uintptr_t async_resource_handle); 1099 1100 private: 1101 inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>, 1102 v8::Local<v8::Value>), 1103 const char* errmsg); 1104 void TrackContext(v8::Local<v8::Context> context); 1105 void UntrackContext(v8::Local<v8::Context> context); 1106 1107 std::list<binding::DLib> loaded_addons_; 1108 v8::Isolate* const isolate_; 1109 IsolateData* const isolate_data_; 1110 1111 bool env_handle_initialized_ = false; 1112 uv_timer_t timer_handle_; 1113 uv_check_t immediate_check_handle_; 1114 uv_idle_t immediate_idle_handle_; 1115 uv_prepare_t idle_prepare_handle_; 1116 uv_check_t idle_check_handle_; 1117 uv_async_t task_queues_async_; 1118 int64_t task_queues_async_refs_ = 0; 1119 1120 // These may be read by ctors and should be listed before complex fields. 1121 std::atomic_bool is_stopping_{false}; 1122 std::atomic_bool can_call_into_js_{true}; 1123 1124 AsyncHooks async_hooks_; 1125 ImmediateInfo immediate_info_; 1126 AliasedInt32Array timeout_info_; 1127 TickInfo tick_info_; 1128 permission::Permission permission_; 1129 const uint64_t timer_base_; 1130 std::shared_ptr<KVStore> env_vars_; 1131 bool printed_error_ = false; 1132 bool trace_sync_io_ = false; 1133 bool emit_env_nonstring_warning_ = true; 1134 bool emit_err_name_warning_ = true; 1135 bool emit_filehandle_warning_ = true; 1136 bool source_maps_enabled_ = false; 1137 1138 size_t async_callback_scope_depth_ = 0; 1139 std::vector<double> destroy_async_id_list_; 1140 std::unordered_set<shadow_realm::ShadowRealm*> shadow_realms_; 1141 1142 #if HAVE_INSPECTOR 1143 std::unique_ptr<profiler::V8CoverageConnection> coverage_connection_; 1144 std::unique_ptr<profiler::V8CpuProfilerConnection> cpu_profiler_connection_; 1145 std::string coverage_directory_; 1146 std::string cpu_prof_dir_; 1147 std::string cpu_prof_name_; 1148 uint64_t cpu_prof_interval_; 1149 std::unique_ptr<profiler::V8HeapProfilerConnection> heap_profiler_connection_; 1150 std::string heap_prof_dir_; 1151 std::string heap_prof_name_; 1152 uint64_t heap_prof_interval_; 1153 #endif // HAVE_INSPECTOR 1154 1155 std::unique_ptr<CompileCacheHandler> compile_cache_handler_; 1156 std::shared_ptr<EnvironmentOptions> options_; 1157 // options_ contains debug options parsed from CLI arguments, 1158 // while inspector_host_port_ stores the actual inspector host 1159 // and port being used. For example the port is -1 by default 1160 // and can be specified as 0 (meaning any port allocated when the 1161 // server starts listening), but when the inspector server starts 1162 // the inspector_host_port_->port() will be the actual port being 1163 // used. 1164 std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port_; 1165 std::vector<std::string> exec_argv_; 1166 std::vector<std::string> argv_; 1167 std::string exec_path_; 1168 1169 bool is_in_heapsnapshot_heap_limit_callback_ = false; 1170 uint32_t heap_limit_snapshot_taken_ = 0; 1171 uint32_t heap_snapshot_near_heap_limit_ = 0; 1172 bool heapsnapshot_near_heap_limit_callback_added_ = false; 1173 1174 uint32_t module_id_counter_ = 0; 1175 uint32_t script_id_counter_ = 0; 1176 uint32_t function_id_counter_ = 0; 1177 uint32_t trace_promise_id_counter_ = 0; 1178 1179 AliasedInt32Array exit_info_; 1180 1181 AliasedUint32Array should_abort_on_uncaught_toggle_; 1182 int should_not_abort_scope_counter_ = 0; 1183 1184 std::unique_ptr<TrackingTraceStateObserver> trace_state_observer_; 1185 1186 AliasedInt32Array stream_base_state_; 1187 1188 // As PerformanceNodeTiming is exposed in worker_threads, the per_process 1189 // time origin is exposed in the worker threads. This is an intentional 1190 // diverge from the HTML spec of web workers. 1191 // Process start time from the monotonic clock. This should not be used as an 1192 // absolute time, but only as a time relative to another monotonic clock time. 1193 const uint64_t time_origin_; 1194 // Process start timestamp from the wall clock. This is an absolute time 1195 // exposed as `performance.timeOrigin`. 1196 const double time_origin_timestamp_; 1197 // This is the time when the environment is created. 1198 const uint64_t environment_start_; 1199 std::unique_ptr<performance::PerformanceState> performance_state_; 1200 1201 bool has_serialized_options_ = false; 1202 1203 uint64_t flags_; 1204 uint64_t thread_id_; 1205 std::string thread_name_; 1206 std::unordered_set<worker::Worker*> sub_worker_contexts_; 1207 1208 #if HAVE_INSPECTOR 1209 std::unique_ptr<inspector::Agent> inspector_agent_; 1210 bool is_in_inspector_console_call_ = false; 1211 #endif 1212 1213 std::list<DeserializeRequest> deserialize_requests_; 1214 1215 // handle_wrap_queue_ and req_wrap_queue_ needs to be at a fixed offset from 1216 // the start of the class because it is used by 1217 // src/node_postmortem_metadata.cc to calculate offsets and generate debug 1218 // symbols for Environment, which assumes that the position of members in 1219 // memory are predictable. For more information please refer to 1220 // `doc/contributing/node-postmortem-support.md` 1221 friend int GenDebugSymbols(); 1222 CleanableQueue cleanable_queue_; 1223 HandleWrapQueue handle_wrap_queue_; 1224 ReqWrapQueue req_wrap_queue_; 1225 int handle_cleanup_waiting_ = 0; 1226 int request_waiting_ = 0; 1227 1228 EnabledDebugList enabled_debug_list_; 1229 1230 std::vector<v8::Global<v8::Context>> contexts_; 1231 std::list<node_module> extra_linked_bindings_; 1232 Mutex extra_linked_bindings_mutex_; 1233 1234 static void RunTimers(uv_timer_t* handle); 1235 1236 struct ExitCallback { 1237 void (*cb_)(void* arg); 1238 void* arg_; 1239 }; 1240 1241 std::list<ExitCallback> at_exit_functions_; 1242 1243 typedef CallbackQueue<void, Environment*> NativeImmediateQueue; 1244 NativeImmediateQueue native_immediates_; 1245 Mutex native_immediates_threadsafe_mutex_; 1246 NativeImmediateQueue native_immediates_threadsafe_; 1247 NativeImmediateQueue native_immediates_interrupts_; 1248 // Also guarded by native_immediates_threadsafe_mutex_. This can be used when 1249 // trying to post tasks from other threads to an Environment, as the libuv 1250 // handle for the immediate queues (task_queues_async_) may not be initialized 1251 // yet or already have been destroyed. 1252 bool task_queues_async_initialized_ = false; 1253 1254 std::atomic<Environment**> interrupt_data_ {nullptr}; 1255 void RequestInterruptFromV8(); 1256 static void CheckImmediate(uv_check_t* handle); 1257 1258 CleanupQueue cleanup_queue_; 1259 bool started_cleanup_ = false; 1260 1261 std::unordered_set<int> unmanaged_fds_; 1262 1263 std::function<void(Environment*, ExitCode)> process_exit_handler_{ 1264 DefaultProcessExitHandlerInternal}; 1265 1266 std::unique_ptr<PrincipalRealm> principal_realm_ = nullptr; 1267 1268 builtins::BuiltinLoader builtin_loader_; 1269 EmbedderPreloadCallback embedder_preload_; 1270 1271 // Used by allocate_managed_buffer() and release_managed_buffer() to keep 1272 // track of the BackingStore for a given pointer. 1273 std::unordered_map<char*, std::unique_ptr<v8::BackingStore>> 1274 released_allocated_buffers_; 1275 1276 std::unordered_map<std::uintptr_t, v8::Global<v8::Value>> 1277 async_resource_context_frames_; 1278 1279 v8::CpuProfiler* cpu_profiler_ = nullptr; 1280 std::unordered_map<std::string, v8::ProfilerId> pending_profiles_; 1281 }; 1282 1283 } // namespace node 1284 1285 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 1286 1287 #endif // SRC_ENV_H_