The C and C++ Include Header Files
/usr/include/nodejs/src/env.h
$ 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 "debug_utils.h" 35 #include "env_properties.h" 36 #include "handle_wrap.h" 37 #include "node.h" 38 #include "node_binding.h" 39 #include "node_builtins.h" 40 #include "node_main_instance.h" 41 #include "node_options.h" 42 #include "node_perf_common.h" 43 #include "node_realm.h" 44 #include "node_snapshotable.h" 45 #include "req_wrap.h" 46 #include "util.h" 47 #include "uv.h" 48 #include "v8.h" 49 50 #include <array> 51 #include <atomic> 52 #include <cstdint> 53 #include <functional> 54 #include <list> 55 #include <memory> 56 #include <ostream> 57 #include <set> 58 #include <string> 59 #include <unordered_map> 60 #include <unordered_set> 61 #include <vector> 62 63 namespace node { 64 65 namespace contextify { 66 class ContextifyScript; 67 class CompiledFnEntry; 68 } 69 70 namespace performance { 71 class PerformanceState; 72 } 73 74 namespace tracing { 75 class AgentWriterHandle; 76 } 77 78 #if HAVE_INSPECTOR 79 namespace profiler { 80 class V8CoverageConnection; 81 class V8CpuProfilerConnection; 82 class V8HeapProfilerConnection; 83 } // namespace profiler 84 85 namespace inspector { 86 class ParentInspectorHandle; 87 } 88 #endif // HAVE_INSPECTOR 89 90 namespace worker { 91 class Worker; 92 } 93 94 namespace loader { 95 class ModuleWrap; 96 } // namespace loader 97 98 class Environment; 99 class Realm; 100 101 // Disables zero-filling for ArrayBuffer allocations in this scope. This is 102 // similar to how we implement Buffer.allocUnsafe() in JS land. 103 class NoArrayBufferZeroFillScope { 104 public: 105 inline explicit NoArrayBufferZeroFillScope(IsolateData* isolate_data); 106 inline ~NoArrayBufferZeroFillScope(); 107 108 private: 109 NodeArrayBufferAllocator* node_allocator_; 110 111 friend class Environment; 112 }; 113 114 struct IsolateDataSerializeInfo { 115 std::vector<SnapshotIndex> primitive_values; 116 std::vector<PropInfo> template_values; 117 118 friend std::ostream& operator<<(std::ostream& o, 119 const IsolateDataSerializeInfo& i); 120 }; 121 122 class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { 123 public: 124 IsolateData(v8::Isolate* isolate, 125 uv_loop_t* event_loop, 126 MultiIsolatePlatform* platform = nullptr, 127 ArrayBufferAllocator* node_allocator = nullptr, 128 const IsolateDataSerializeInfo* isolate_data_info = nullptr); 129 SET_MEMORY_INFO_NAME(IsolateData) 130 SET_SELF_SIZE(IsolateData) 131 void MemoryInfo(MemoryTracker* tracker) const override; 132 IsolateDataSerializeInfo Serialize(v8::SnapshotCreator* creator); 133 134 inline uv_loop_t* event_loop() const; 135 inline MultiIsolatePlatform* platform() const; 136 inline std::shared_ptr<PerIsolateOptions> options(); 137 inline void set_options(std::shared_ptr<PerIsolateOptions> options); 138 139 inline NodeArrayBufferAllocator* node_allocator() const; 140 141 inline worker::Worker* worker_context() const; 142 inline void set_worker_context(worker::Worker* context); 143 144 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 145 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 146 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 147 #define V(TypeName, PropertyName) \ 148 inline v8::Local<TypeName> PropertyName() const; 149 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 150 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 151 PER_ISOLATE_STRING_PROPERTIES(VS) 152 #undef V 153 #undef VY 154 #undef VS 155 #undef VP 156 157 #define VM(PropertyName) V(PropertyName##_binding, v8::FunctionTemplate) 158 #define V(PropertyName, TypeName) \ 159 inline v8::Local<TypeName> PropertyName() const; \ 160 inline void set_##PropertyName(v8::Local<TypeName> value); 161 PER_ISOLATE_TEMPLATE_PROPERTIES(V) 162 NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) 163 #undef V 164 #undef VM 165 166 inline v8::Local<v8::String> async_wrap_provider(int index) const; 167 168 size_t max_young_gen_size = 1; 169 std::unordered_map<const char*, v8::Eternal<v8::String>> static_str_map; 170 171 inline v8::Isolate* isolate() const; 172 IsolateData(const IsolateData&) = delete; 173 IsolateData& operator=(const IsolateData&) = delete; 174 IsolateData(IsolateData&&) = delete; 175 IsolateData& operator=(IsolateData&&) = delete; 176 177 private: 178 void DeserializeProperties(const IsolateDataSerializeInfo* isolate_data_info); 179 void CreateProperties(); 180 181 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 182 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 183 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 184 #define VM(PropertyName) V(v8::FunctionTemplate, PropertyName##_binding) 185 #define VT(PropertyName, TypeName) V(TypeName, PropertyName) 186 #define V(TypeName, PropertyName) \ 187 v8::Eternal<TypeName> PropertyName ## _; 188 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 189 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 190 PER_ISOLATE_STRING_PROPERTIES(VS) 191 PER_ISOLATE_TEMPLATE_PROPERTIES(VT) 192 NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM) 193 #undef V 194 #undef VM 195 #undef VT 196 #undef VS 197 #undef VY 198 #undef VP 199 // Keep a list of all Persistent strings used for AsyncWrap Provider types. 200 std::array<v8::Eternal<v8::String>, AsyncWrap::PROVIDERS_LENGTH> 201 async_wrap_providers_; 202 203 v8::Isolate* const isolate_; 204 uv_loop_t* const event_loop_; 205 NodeArrayBufferAllocator* const node_allocator_; 206 MultiIsolatePlatform* platform_; 207 std::shared_ptr<PerIsolateOptions> options_; 208 worker::Worker* worker_context_ = nullptr; 209 }; 210 211 struct ContextInfo { 212 explicit ContextInfo(const std::string& name) : name(name) {} 213 const std::string name; 214 std::string origin; 215 bool is_default = false; 216 }; 217 218 class EnabledDebugList; 219 220 namespace per_process { 221 extern std::shared_ptr<KVStore> system_environment; 222 } 223 224 struct EnvSerializeInfo; 225 226 class AsyncHooks : public MemoryRetainer { 227 public: 228 SET_MEMORY_INFO_NAME(AsyncHooks) 229 SET_SELF_SIZE(AsyncHooks) 230 void MemoryInfo(MemoryTracker* tracker) const override; 231 232 // Reason for both UidFields and Fields are that one is stored as a double* 233 // and the other as a uint32_t*. 234 enum Fields { 235 kInit, 236 kBefore, 237 kAfter, 238 kDestroy, 239 kPromiseResolve, 240 kTotals, 241 kCheck, 242 kStackLength, 243 kUsesExecutionAsyncResource, 244 kFieldsCount, 245 }; 246 247 enum UidFields { 248 kExecutionAsyncId, 249 kTriggerAsyncId, 250 kAsyncIdCounter, 251 kDefaultTriggerAsyncId, 252 kUidFieldsCount, 253 }; 254 255 inline AliasedUint32Array& fields(); 256 inline AliasedFloat64Array& async_id_fields(); 257 inline AliasedFloat64Array& async_ids_stack(); 258 inline v8::Local<v8::Array> js_execution_async_resources(); 259 // Returns the native executionAsyncResource value at stack index `index`. 260 // Resources provided on the JS side are not stored on the native stack, 261 // in which case an empty `Local<>` is returned. 262 // The `js_execution_async_resources` array contains the value in that case. 263 inline v8::Local<v8::Object> native_execution_async_resource(size_t index); 264 265 void InstallPromiseHooks(v8::Local<v8::Context> ctx); 266 void ResetPromiseHooks(v8::Local<v8::Function> init, 267 v8::Local<v8::Function> before, 268 v8::Local<v8::Function> after, 269 v8::Local<v8::Function> resolve); 270 271 inline v8::Local<v8::String> provider_string(int idx); 272 273 inline void no_force_checks(); 274 inline Environment* env(); 275 276 // NB: This call does not take (co-)ownership of `execution_async_resource`. 277 // The lifetime of the `v8::Local<>` pointee must last until 278 // `pop_async_context()` or `clear_async_id_stack()` are called. 279 void push_async_context(double async_id, 280 double trigger_async_id, 281 v8::Local<v8::Object> execution_async_resource); 282 bool pop_async_context(double async_id); 283 void clear_async_id_stack(); // Used in fatal exceptions. 284 285 AsyncHooks(const AsyncHooks&) = delete; 286 AsyncHooks& operator=(const AsyncHooks&) = delete; 287 AsyncHooks(AsyncHooks&&) = delete; 288 AsyncHooks& operator=(AsyncHooks&&) = delete; 289 ~AsyncHooks() = default; 290 291 // Used to set the kDefaultTriggerAsyncId in a scope. This is instead of 292 // passing the trigger_async_id along with other constructor arguments. 293 class DefaultTriggerAsyncIdScope { 294 public: 295 DefaultTriggerAsyncIdScope() = delete; 296 explicit DefaultTriggerAsyncIdScope(Environment* env, 297 double init_trigger_async_id); 298 explicit DefaultTriggerAsyncIdScope(AsyncWrap* async_wrap); 299 ~DefaultTriggerAsyncIdScope(); 300 301 DefaultTriggerAsyncIdScope(const DefaultTriggerAsyncIdScope&) = delete; 302 DefaultTriggerAsyncIdScope& operator=(const DefaultTriggerAsyncIdScope&) = 303 delete; 304 DefaultTriggerAsyncIdScope(DefaultTriggerAsyncIdScope&&) = delete; 305 DefaultTriggerAsyncIdScope& operator=(DefaultTriggerAsyncIdScope&&) = 306 delete; 307 308 private: 309 AsyncHooks* async_hooks_; 310 double old_default_trigger_async_id_; 311 }; 312 313 struct SerializeInfo { 314 AliasedBufferIndex async_ids_stack; 315 AliasedBufferIndex fields; 316 AliasedBufferIndex async_id_fields; 317 SnapshotIndex js_execution_async_resources; 318 std::vector<SnapshotIndex> native_execution_async_resources; 319 }; 320 321 SerializeInfo Serialize(v8::Local<v8::Context> context, 322 v8::SnapshotCreator* creator); 323 void Deserialize(v8::Local<v8::Context> context); 324 325 private: 326 friend class Environment; // So we can call the constructor. 327 explicit AsyncHooks(v8::Isolate* isolate, const SerializeInfo* info); 328 329 [[noreturn]] void FailWithCorruptedAsyncStack(double expected_async_id); 330 331 // Stores the ids of the current execution context stack. 332 AliasedFloat64Array async_ids_stack_; 333 // Attached to a Uint32Array that tracks the number of active hooks for 334 // each type. 335 AliasedUint32Array fields_; 336 // Attached to a Float64Array that tracks the state of async resources. 337 AliasedFloat64Array async_id_fields_; 338 339 void grow_async_ids_stack(); 340 341 v8::Global<v8::Array> js_execution_async_resources_; 342 std::vector<v8::Local<v8::Object>> native_execution_async_resources_; 343 344 // Non-empty during deserialization 345 const SerializeInfo* info_ = nullptr; 346 347 std::array<v8::Global<v8::Function>, 4> js_promise_hooks_; 348 }; 349 350 class ImmediateInfo : public MemoryRetainer { 351 public: 352 inline AliasedUint32Array& fields(); 353 inline uint32_t count() const; 354 inline uint32_t ref_count() const; 355 inline bool has_outstanding() const; 356 inline void ref_count_inc(uint32_t increment); 357 inline void ref_count_dec(uint32_t decrement); 358 359 ImmediateInfo(const ImmediateInfo&) = delete; 360 ImmediateInfo& operator=(const ImmediateInfo&) = delete; 361 ImmediateInfo(ImmediateInfo&&) = delete; 362 ImmediateInfo& operator=(ImmediateInfo&&) = delete; 363 ~ImmediateInfo() = default; 364 365 SET_MEMORY_INFO_NAME(ImmediateInfo) 366 SET_SELF_SIZE(ImmediateInfo) 367 void MemoryInfo(MemoryTracker* tracker) const override; 368 369 struct SerializeInfo { 370 AliasedBufferIndex fields; 371 }; 372 SerializeInfo Serialize(v8::Local<v8::Context> context, 373 v8::SnapshotCreator* creator); 374 void Deserialize(v8::Local<v8::Context> context); 375 376 private: 377 friend class Environment; // So we can call the constructor. 378 explicit ImmediateInfo(v8::Isolate* isolate, const SerializeInfo* info); 379 380 enum Fields { kCount, kRefCount, kHasOutstanding, kFieldsCount }; 381 382 AliasedUint32Array fields_; 383 }; 384 385 class TickInfo : public MemoryRetainer { 386 public: 387 inline AliasedUint8Array& fields(); 388 inline bool has_tick_scheduled() const; 389 inline bool has_rejection_to_warn() const; 390 391 SET_MEMORY_INFO_NAME(TickInfo) 392 SET_SELF_SIZE(TickInfo) 393 void MemoryInfo(MemoryTracker* tracker) const override; 394 395 TickInfo(const TickInfo&) = delete; 396 TickInfo& operator=(const TickInfo&) = delete; 397 TickInfo(TickInfo&&) = delete; 398 TickInfo& operator=(TickInfo&&) = delete; 399 ~TickInfo() = default; 400 401 struct SerializeInfo { 402 AliasedBufferIndex fields; 403 }; 404 SerializeInfo Serialize(v8::Local<v8::Context> context, 405 v8::SnapshotCreator* creator); 406 void Deserialize(v8::Local<v8::Context> context); 407 408 private: 409 friend class Environment; // So we can call the constructor. 410 explicit TickInfo(v8::Isolate* isolate, const SerializeInfo* info); 411 412 enum Fields { kHasTickScheduled = 0, kHasRejectionToWarn, kFieldsCount }; 413 414 AliasedUint8Array fields_; 415 }; 416 417 class TrackingTraceStateObserver : 418 public v8::TracingController::TraceStateObserver { 419 public: 420 explicit TrackingTraceStateObserver(Environment* env) : env_(env) {} 421 422 void OnTraceEnabled() override { 423 UpdateTraceCategoryState(); 424 } 425 426 void OnTraceDisabled() override { 427 UpdateTraceCategoryState(); 428 } 429 430 private: 431 void UpdateTraceCategoryState(); 432 433 Environment* env_; 434 }; 435 436 class ShouldNotAbortOnUncaughtScope { 437 public: 438 explicit inline ShouldNotAbortOnUncaughtScope(Environment* env); 439 inline void Close(); 440 inline ~ShouldNotAbortOnUncaughtScope(); 441 ShouldNotAbortOnUncaughtScope(const ShouldNotAbortOnUncaughtScope&) = delete; 442 ShouldNotAbortOnUncaughtScope& operator=( 443 const ShouldNotAbortOnUncaughtScope&) = delete; 444 ShouldNotAbortOnUncaughtScope(ShouldNotAbortOnUncaughtScope&&) = delete; 445 ShouldNotAbortOnUncaughtScope& operator=(ShouldNotAbortOnUncaughtScope&&) = 446 delete; 447 448 private: 449 Environment* env_; 450 }; 451 452 typedef void (*DeserializeRequestCallback)(v8::Local<v8::Context> context, 453 v8::Local<v8::Object> holder, 454 int index, 455 InternalFieldInfoBase* info); 456 struct DeserializeRequest { 457 DeserializeRequestCallback cb; 458 v8::Global<v8::Object> holder; 459 int index; 460 InternalFieldInfoBase* info = nullptr; // Owned by the request 461 }; 462 463 struct EnvSerializeInfo { 464 AsyncHooks::SerializeInfo async_hooks; 465 TickInfo::SerializeInfo tick_info; 466 ImmediateInfo::SerializeInfo immediate_info; 467 AliasedBufferIndex timeout_info; 468 performance::PerformanceState::SerializeInfo performance_state; 469 AliasedBufferIndex exiting; 470 AliasedBufferIndex stream_base_state; 471 AliasedBufferIndex should_abort_on_uncaught_toggle; 472 473 RealmSerializeInfo principal_realm; 474 friend std::ostream& operator<<(std::ostream& o, const EnvSerializeInfo& i); 475 }; 476 477 struct SnapshotMetadata { 478 // For now kFullyCustomized is only built with the --build-snapshot CLI flag. 479 // We might want to add more types of snapshots in the future. 480 enum class Type : uint8_t { kDefault, kFullyCustomized }; 481 482 Type type; 483 std::string node_version; 484 std::string node_arch; 485 std::string node_platform; 486 // Result of v8::ScriptCompiler::CachedDataVersionTag(). 487 uint32_t v8_cache_version_tag; 488 }; 489 490 struct SnapshotData { 491 enum class DataOwnership { kOwned, kNotOwned }; 492 493 static const uint32_t kMagic = 0x143da19; 494 static const SnapshotIndex kNodeVMContextIndex = 0; 495 static const SnapshotIndex kNodeBaseContextIndex = kNodeVMContextIndex + 1; 496 static const SnapshotIndex kNodeMainContextIndex = kNodeBaseContextIndex + 1; 497 498 DataOwnership data_ownership = DataOwnership::kOwned; 499 500 SnapshotMetadata metadata; 501 502 // The result of v8::SnapshotCreator::CreateBlob() during the snapshot 503 // building process. 504 v8::StartupData v8_snapshot_blob_data{nullptr, 0}; 505 506 IsolateDataSerializeInfo isolate_data_info; 507 // TODO(joyeecheung): there should be a vector of env_info once we snapshot 508 // the worker environments. 509 EnvSerializeInfo env_info; 510 511 // A vector of built-in ids and v8::ScriptCompiler::CachedData, this can be 512 // shared across Node.js instances because they are supposed to share the 513 // read only space. We use builtins::CodeCacheInfo because 514 // v8::ScriptCompiler::CachedData is not copyable. 515 std::vector<builtins::CodeCacheInfo> code_cache; 516 517 void ToBlob(FILE* out) const; 518 // If returns false, the metadata doesn't match the current Node.js binary, 519 // and the caller should not consume the snapshot data. 520 bool Check() const; 521 static bool FromBlob(SnapshotData* out, FILE* in); 522 523 ~SnapshotData(); 524 }; 525 526 /** 527 * Environment is a per-isolate data structure that represents an execution 528 * environment. Each environment has a principal realm. An environment can 529 * create multiple subsidiary synthetic realms. 530 */ 531 class Environment : public MemoryRetainer { 532 public: 533 Environment(const Environment&) = delete; 534 Environment& operator=(const Environment&) = delete; 535 Environment(Environment&&) = delete; 536 Environment& operator=(Environment&&) = delete; 537 538 SET_MEMORY_INFO_NAME(Environment) 539 540 inline size_t SelfSize() const override; 541 bool IsRootNode() const override { return true; } 542 void MemoryInfo(MemoryTracker* tracker) const override; 543 544 EnvSerializeInfo Serialize(v8::SnapshotCreator* creator); 545 void DeserializeProperties(const EnvSerializeInfo* info); 546 547 void PrintInfoForSnapshotIfDebug(); 548 void EnqueueDeserializeRequest(DeserializeRequestCallback cb, 549 v8::Local<v8::Object> holder, 550 int index, 551 InternalFieldInfoBase* info); 552 void RunDeserializeRequests(); 553 // Should be called before InitializeInspector() 554 void InitializeDiagnostics(); 555 556 std::string GetCwd(); 557 558 #if HAVE_INSPECTOR 559 // If the environment is created for a worker, pass parent_handle and 560 // the ownership if transferred into the Environment. 561 int InitializeInspector( 562 std::unique_ptr<inspector::ParentInspectorHandle> parent_handle); 563 #endif 564 565 inline size_t async_callback_scope_depth() const; 566 inline void PushAsyncCallbackScope(); 567 inline void PopAsyncCallbackScope(); 568 569 static inline Environment* GetCurrent(v8::Isolate* isolate); 570 static inline Environment* GetCurrent(v8::Local<v8::Context> context); 571 static inline Environment* GetCurrent( 572 const v8::FunctionCallbackInfo<v8::Value>& info); 573 574 template <typename T> 575 static inline Environment* GetCurrent( 576 const v8::PropertyCallbackInfo<T>& info); 577 578 // Create an Environment without initializing a main Context. Use 579 // InitializeMainContext() to initialize a main context for it. 580 Environment(IsolateData* isolate_data, 581 v8::Isolate* isolate, 582 const std::vector<std::string>& args, 583 const std::vector<std::string>& exec_args, 584 const EnvSerializeInfo* env_info, 585 EnvironmentFlags::Flags flags, 586 ThreadId thread_id); 587 void InitializeMainContext(v8::Local<v8::Context> context, 588 const EnvSerializeInfo* env_info); 589 // Create an Environment and initialize the provided principal context for it. 590 Environment(IsolateData* isolate_data, 591 v8::Local<v8::Context> context, 592 const std::vector<std::string>& args, 593 const std::vector<std::string>& exec_args, 594 const EnvSerializeInfo* env_info, 595 EnvironmentFlags::Flags flags, 596 ThreadId thread_id); 597 ~Environment() override; 598 599 void InitializeLibuv(); 600 inline const std::vector<std::string>& exec_argv(); 601 inline const std::vector<std::string>& argv(); 602 const std::string& exec_path() const; 603 604 typedef void (*HandleCleanupCb)(Environment* env, 605 uv_handle_t* handle, 606 void* arg); 607 struct HandleCleanup { 608 uv_handle_t* handle_; 609 HandleCleanupCb cb_; 610 void* arg_; 611 }; 612 613 void RegisterHandleCleanups(); 614 void CleanupHandles(); 615 void Exit(int code); 616 void ExitEnv(StopFlags::Flags flags); 617 618 // Register clean-up cb to be called on environment destruction. 619 inline void RegisterHandleCleanup(uv_handle_t* handle, 620 HandleCleanupCb cb, 621 void* arg); 622 623 template <typename T, typename OnCloseCallback> 624 inline void CloseHandle(T* handle, OnCloseCallback callback); 625 626 void ResetPromiseHooks(v8::Local<v8::Function> init, 627 v8::Local<v8::Function> before, 628 v8::Local<v8::Function> after, 629 v8::Local<v8::Function> resolve); 630 void AssignToContext(v8::Local<v8::Context> context, 631 Realm* realm, 632 const ContextInfo& info); 633 void TrackContext(v8::Local<v8::Context> context); 634 void UntrackContext(v8::Local<v8::Context> context); 635 636 void StartProfilerIdleNotifier(); 637 638 inline v8::Isolate* isolate() const; 639 inline uv_loop_t* event_loop() const; 640 void TryLoadAddon(const char* filename, 641 int flags, 642 const std::function<bool(binding::DLib*)>& was_loaded); 643 644 static inline Environment* from_timer_handle(uv_timer_t* handle); 645 inline uv_timer_t* timer_handle(); 646 647 static inline Environment* from_immediate_check_handle(uv_check_t* handle); 648 inline uv_check_t* immediate_check_handle(); 649 inline uv_idle_t* immediate_idle_handle(); 650 651 inline void IncreaseWaitingRequestCounter(); 652 inline void DecreaseWaitingRequestCounter(); 653 654 inline AsyncHooks* async_hooks(); 655 inline ImmediateInfo* immediate_info(); 656 inline AliasedInt32Array& timeout_info(); 657 inline TickInfo* tick_info(); 658 inline uint64_t timer_base() const; 659 inline std::shared_ptr<KVStore> env_vars(); 660 inline void set_env_vars(std::shared_ptr<KVStore> env_vars); 661 662 inline IsolateData* isolate_data() const; 663 664 inline bool printed_error() const; 665 inline void set_printed_error(bool value); 666 667 void PrintSyncTrace() const; 668 inline void set_trace_sync_io(bool value); 669 670 inline void set_force_context_aware(bool value); 671 inline bool force_context_aware() const; 672 673 // This is a pseudo-boolean that keeps track of whether the process is 674 // exiting. 675 inline void set_exiting(bool value); 676 inline AliasedUint32Array& exiting(); 677 678 // This stores whether the --abort-on-uncaught-exception flag was passed 679 // to Node. 680 inline bool abort_on_uncaught_exception() const; 681 inline void set_abort_on_uncaught_exception(bool value); 682 // This is a pseudo-boolean that keeps track of whether an uncaught exception 683 // should abort the process or not if --abort-on-uncaught-exception was 684 // passed to Node. If the flag was not passed, it is ignored. 685 inline AliasedUint32Array& should_abort_on_uncaught_toggle(); 686 687 inline AliasedInt32Array& stream_base_state(); 688 689 // The necessary API for async_hooks. 690 inline double new_async_id(); 691 inline double execution_async_id(); 692 inline double trigger_async_id(); 693 inline double get_default_trigger_async_id(); 694 695 // List of id's that have been destroyed and need the destroy() cb called. 696 inline std::vector<double>* destroy_async_id_list(); 697 698 builtins::BuiltinLoader* builtin_loader(); 699 700 std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map; 701 std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map; 702 std::unordered_map<uint32_t, contextify::ContextifyScript*> 703 id_to_script_map; 704 std::unordered_map<uint32_t, contextify::CompiledFnEntry*> id_to_function_map; 705 706 inline uint32_t get_next_module_id(); 707 inline uint32_t get_next_script_id(); 708 inline uint32_t get_next_function_id(); 709 710 EnabledDebugList* enabled_debug_list() { return &enabled_debug_list_; } 711 712 inline performance::PerformanceState* performance_state(); 713 714 void CollectUVExceptionInfo(v8::Local<v8::Value> context, 715 int errorno, 716 const char* syscall = nullptr, 717 const char* message = nullptr, 718 const char* path = nullptr, 719 const char* dest = nullptr); 720 721 // If this flag is set, calls into JS (if they would be observable 722 // from userland) must be avoided. This flag does not indicate whether 723 // calling into JS is allowed from a VM perspective at this point. 724 inline bool can_call_into_js() const; 725 inline void set_can_call_into_js(bool can_call_into_js); 726 727 // Increase or decrease a counter that manages whether this Environment 728 // keeps the event loop alive on its own or not. The counter starts out at 0, 729 // meaning it does not, and any positive value will make it keep the event 730 // loop alive. 731 // This is used by Workers to manage their own .ref()/.unref() implementation, 732 // as Workers aren't directly associated with their own libuv handles. 733 void add_refs(int64_t diff); 734 735 // Convenient getter of the principal realm's has_run_bootstrapping_code(). 736 inline bool has_run_bootstrapping_code() const; 737 738 inline bool has_serialized_options() const; 739 inline void set_has_serialized_options(bool has_serialized_options); 740 741 inline bool is_main_thread() const; 742 inline bool no_native_addons() const; 743 inline bool should_not_register_esm_loader() const; 744 inline bool should_create_inspector() const; 745 inline bool owns_process_state() const; 746 inline bool owns_inspector() const; 747 inline bool tracks_unmanaged_fds() const; 748 inline bool hide_console_windows() const; 749 inline bool no_global_search_paths() const; 750 inline bool no_browser_globals() const; 751 inline uint64_t thread_id() const; 752 inline worker::Worker* worker_context() const; 753 Environment* worker_parent_env() const; 754 inline void add_sub_worker_context(worker::Worker* context); 755 inline void remove_sub_worker_context(worker::Worker* context); 756 void stop_sub_worker_contexts(); 757 template <typename Fn> 758 inline void ForEachWorker(Fn&& iterator); 759 // Determine if the environment is stopping. This getter is thread-safe. 760 inline bool is_stopping() const; 761 inline void set_stopping(bool value); 762 inline std::list<node_module>* extra_linked_bindings(); 763 inline node_module* extra_linked_bindings_head(); 764 inline node_module* extra_linked_bindings_tail(); 765 inline const Mutex& extra_linked_bindings_mutex() const; 766 767 inline bool filehandle_close_warning() const; 768 inline void set_filehandle_close_warning(bool on); 769 770 inline void set_source_maps_enabled(bool on); 771 inline bool source_maps_enabled() const; 772 773 inline void ThrowError(const char* errmsg); 774 inline void ThrowTypeError(const char* errmsg); 775 inline void ThrowRangeError(const char* errmsg); 776 inline void ThrowErrnoException(int errorno, 777 const char* syscall = nullptr, 778 const char* message = nullptr, 779 const char* path = nullptr); 780 inline void ThrowUVException(int errorno, 781 const char* syscall = nullptr, 782 const char* message = nullptr, 783 const char* path = nullptr, 784 const char* dest = nullptr); 785 786 void AtExit(void (*cb)(void* arg), void* arg); 787 void RunAtExitCallbacks(); 788 789 void RunWeakRefCleanup(); 790 791 v8::MaybeLocal<v8::Value> RunSnapshotSerializeCallback() const; 792 v8::MaybeLocal<v8::Value> RunSnapshotDeserializeCallback() const; 793 v8::MaybeLocal<v8::Value> RunSnapshotDeserializeMain() const; 794 795 // Primitive values are shared across realms. 796 // The getters simply proxy to the per-isolate primitive. 797 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 798 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 799 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 800 #define V(TypeName, PropertyName) \ 801 inline v8::Local<TypeName> PropertyName() const; 802 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 803 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 804 PER_ISOLATE_STRING_PROPERTIES(VS) 805 #undef V 806 #undef VS 807 #undef VY 808 #undef VP 809 810 #define V(PropertyName, TypeName) \ 811 inline v8::Local<TypeName> PropertyName() const; \ 812 inline void set_ ## PropertyName(v8::Local<TypeName> value); 813 PER_ISOLATE_TEMPLATE_PROPERTIES(V) 814 // Per-realm strong persistent values of the principal realm. 815 // Get/set the value with an explicit realm instead when possible. 816 // Deprecate soon. 817 PER_REALM_STRONG_PERSISTENT_VALUES(V) 818 #undef V 819 820 // Return the context of the principal realm. 821 // Get the context with an explicit realm instead when possible. 822 // Deprecate soon. 823 inline v8::Local<v8::Context> context() const; 824 inline Realm* principal_realm() const; 825 826 #if HAVE_INSPECTOR 827 inline inspector::Agent* inspector_agent() const { 828 return inspector_agent_.get(); 829 } 830 831 inline bool is_in_inspector_console_call() const; 832 inline void set_is_in_inspector_console_call(bool value); 833 #endif 834 835 typedef ListHead<HandleWrap, &HandleWrap::handle_wrap_queue_> HandleWrapQueue; 836 typedef ListHead<ReqWrapBase, &ReqWrapBase::req_wrap_queue_> ReqWrapQueue; 837 838 inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } 839 inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } 840 841 inline bool EmitProcessEnvWarning() { 842 bool current_value = emit_env_nonstring_warning_; 843 emit_env_nonstring_warning_ = false; 844 return current_value; 845 } 846 847 inline bool EmitErrNameWarning() { 848 bool current_value = emit_err_name_warning_; 849 emit_err_name_warning_ = false; 850 return current_value; 851 } 852 853 // cb will be called as cb(env) on the next event loop iteration. 854 // Unlike the JS setImmediate() function, nested SetImmediate() calls will 855 // be run without returning control to the event loop, similar to nextTick(). 856 template <typename Fn> 857 inline void SetImmediate( 858 Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed); 859 template <typename Fn> 860 // This behaves like SetImmediate() but can be called from any thread. 861 inline void SetImmediateThreadsafe( 862 Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed); 863 // This behaves like V8's Isolate::RequestInterrupt(), but also accounts for 864 // the event loop (i.e. combines the V8 function with SetImmediate()). 865 // The passed callback may not throw exceptions. 866 // This function can be called from any thread. 867 template <typename Fn> 868 inline void RequestInterrupt(Fn&& cb); 869 // This needs to be available for the JS-land setImmediate(). 870 void ToggleImmediateRef(bool ref); 871 872 inline void PushShouldNotAbortOnUncaughtScope(); 873 inline void PopShouldNotAbortOnUncaughtScope(); 874 inline bool inside_should_not_abort_on_uncaught_scope() const; 875 876 static inline Environment* ForAsyncHooks(AsyncHooks* hooks); 877 878 v8::Local<v8::Value> GetNow(); 879 void ScheduleTimer(int64_t duration); 880 void ToggleTimerRef(bool ref); 881 882 inline void AddCleanupHook(CleanupQueue::Callback cb, void* arg); 883 inline void RemoveCleanupHook(CleanupQueue::Callback cb, void* arg); 884 void RunCleanup(); 885 886 static size_t NearHeapLimitCallback(void* data, 887 size_t current_heap_limit, 888 size_t initial_heap_limit); 889 static void BuildEmbedderGraph(v8::Isolate* isolate, 890 v8::EmbedderGraph* graph, 891 void* data); 892 893 inline std::shared_ptr<EnvironmentOptions> options(); 894 inline std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port(); 895 896 inline int32_t stack_trace_limit() const { return 10; } 897 898 #if HAVE_INSPECTOR 899 void set_coverage_connection( 900 std::unique_ptr<profiler::V8CoverageConnection> connection); 901 profiler::V8CoverageConnection* coverage_connection(); 902 903 inline void set_coverage_directory(const char* directory); 904 inline const std::string& coverage_directory() const; 905 906 void set_cpu_profiler_connection( 907 std::unique_ptr<profiler::V8CpuProfilerConnection> connection); 908 profiler::V8CpuProfilerConnection* cpu_profiler_connection(); 909 910 inline void set_cpu_prof_name(const std::string& name); 911 inline const std::string& cpu_prof_name() const; 912 913 inline void set_cpu_prof_interval(uint64_t interval); 914 inline uint64_t cpu_prof_interval() const; 915 916 inline void set_cpu_prof_dir(const std::string& dir); 917 inline const std::string& cpu_prof_dir() const; 918 919 void set_heap_profiler_connection( 920 std::unique_ptr<profiler::V8HeapProfilerConnection> connection); 921 profiler::V8HeapProfilerConnection* heap_profiler_connection(); 922 923 inline void set_heap_prof_name(const std::string& name); 924 inline const std::string& heap_prof_name() const; 925 926 inline void set_heap_prof_dir(const std::string& dir); 927 inline const std::string& heap_prof_dir() const; 928 929 inline void set_heap_prof_interval(uint64_t interval); 930 inline uint64_t heap_prof_interval() const; 931 932 #endif // HAVE_INSPECTOR 933 934 inline void set_process_exit_handler( 935 std::function<void(Environment*, int)>&& handler); 936 937 void RunAndClearNativeImmediates(bool only_refed = false); 938 void RunAndClearInterrupts(); 939 940 uv_buf_t allocate_managed_buffer(const size_t suggested_size); 941 std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf); 942 943 void AddUnmanagedFd(int fd); 944 void RemoveUnmanagedFd(int fd); 945 946 template <typename T> 947 void ForEachRealm(T&& iterator) const; 948 949 inline void set_heap_snapshot_near_heap_limit(uint32_t limit); 950 inline bool is_in_heapsnapshot_heap_limit_callback() const; 951 952 inline void AddHeapSnapshotNearHeapLimitCallback(); 953 954 inline void RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit); 955 956 private: 957 inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), 958 const char* errmsg); 959 960 std::list<binding::DLib> loaded_addons_; 961 v8::Isolate* const isolate_; 962 IsolateData* const isolate_data_; 963 uv_timer_t timer_handle_; 964 uv_check_t immediate_check_handle_; 965 uv_idle_t immediate_idle_handle_; 966 uv_prepare_t idle_prepare_handle_; 967 uv_check_t idle_check_handle_; 968 uv_async_t task_queues_async_; 969 int64_t task_queues_async_refs_ = 0; 970 971 // These may be read by ctors and should be listed before complex fields. 972 std::atomic_bool is_stopping_{false}; 973 std::atomic_bool can_call_into_js_{true}; 974 975 AsyncHooks async_hooks_; 976 ImmediateInfo immediate_info_; 977 AliasedInt32Array timeout_info_; 978 TickInfo tick_info_; 979 const uint64_t timer_base_; 980 std::shared_ptr<KVStore> env_vars_; 981 bool printed_error_ = false; 982 bool trace_sync_io_ = false; 983 bool emit_env_nonstring_warning_ = true; 984 bool emit_err_name_warning_ = true; 985 bool emit_filehandle_warning_ = true; 986 bool source_maps_enabled_ = false; 987 988 size_t async_callback_scope_depth_ = 0; 989 std::vector<double> destroy_async_id_list_; 990 991 #if HAVE_INSPECTOR 992 std::unique_ptr<profiler::V8CoverageConnection> coverage_connection_; 993 std::unique_ptr<profiler::V8CpuProfilerConnection> cpu_profiler_connection_; 994 std::string coverage_directory_; 995 std::string cpu_prof_dir_; 996 std::string cpu_prof_name_; 997 uint64_t cpu_prof_interval_; 998 std::unique_ptr<profiler::V8HeapProfilerConnection> heap_profiler_connection_; 999 std::string heap_prof_dir_; 1000 std::string heap_prof_name_; 1001 uint64_t heap_prof_interval_; 1002 #endif // HAVE_INSPECTOR 1003 1004 std::shared_ptr<EnvironmentOptions> options_; 1005 // options_ contains debug options parsed from CLI arguments, 1006 // while inspector_host_port_ stores the actual inspector host 1007 // and port being used. For example the port is -1 by default 1008 // and can be specified as 0 (meaning any port allocated when the 1009 // server starts listening), but when the inspector server starts 1010 // the inspector_host_port_->port() will be the actual port being 1011 // used. 1012 std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port_; 1013 std::vector<std::string> exec_argv_; 1014 std::vector<std::string> argv_; 1015 std::string exec_path_; 1016 1017 bool is_in_heapsnapshot_heap_limit_callback_ = false; 1018 uint32_t heap_limit_snapshot_taken_ = 0; 1019 uint32_t heap_snapshot_near_heap_limit_ = 0; 1020 bool heapsnapshot_near_heap_limit_callback_added_ = false; 1021 1022 uint32_t module_id_counter_ = 0; 1023 uint32_t script_id_counter_ = 0; 1024 uint32_t function_id_counter_ = 0; 1025 1026 AliasedUint32Array exiting_; 1027 1028 AliasedUint32Array should_abort_on_uncaught_toggle_; 1029 int should_not_abort_scope_counter_ = 0; 1030 1031 std::unique_ptr<TrackingTraceStateObserver> trace_state_observer_; 1032 1033 AliasedInt32Array stream_base_state_; 1034 1035 uint64_t environment_start_time_; 1036 std::unique_ptr<performance::PerformanceState> performance_state_; 1037 1038 bool has_serialized_options_ = false; 1039 1040 uint64_t flags_; 1041 uint64_t thread_id_; 1042 std::unordered_set<worker::Worker*> sub_worker_contexts_; 1043 1044 #if HAVE_INSPECTOR 1045 std::unique_ptr<inspector::Agent> inspector_agent_; 1046 bool is_in_inspector_console_call_ = false; 1047 #endif 1048 1049 std::list<DeserializeRequest> deserialize_requests_; 1050 1051 // handle_wrap_queue_ and req_wrap_queue_ needs to be at a fixed offset from 1052 // the start of the class because it is used by 1053 // src/node_postmortem_metadata.cc to calculate offsets and generate debug 1054 // symbols for Environment, which assumes that the position of members in 1055 // memory are predictable. For more information please refer to 1056 // `doc/contributing/node-postmortem-support.md` 1057 friend int GenDebugSymbols(); 1058 HandleWrapQueue handle_wrap_queue_; 1059 ReqWrapQueue req_wrap_queue_; 1060 std::list<HandleCleanup> handle_cleanup_queue_; 1061 int handle_cleanup_waiting_ = 0; 1062 int request_waiting_ = 0; 1063 1064 EnabledDebugList enabled_debug_list_; 1065 1066 std::vector<v8::Global<v8::Context>> contexts_; 1067 std::list<node_module> extra_linked_bindings_; 1068 Mutex extra_linked_bindings_mutex_; 1069 1070 static void RunTimers(uv_timer_t* handle); 1071 1072 struct ExitCallback { 1073 void (*cb_)(void* arg); 1074 void* arg_; 1075 }; 1076 1077 std::list<ExitCallback> at_exit_functions_; 1078 1079 typedef CallbackQueue<void, Environment*> NativeImmediateQueue; 1080 NativeImmediateQueue native_immediates_; 1081 Mutex native_immediates_threadsafe_mutex_; 1082 NativeImmediateQueue native_immediates_threadsafe_; 1083 NativeImmediateQueue native_immediates_interrupts_; 1084 // Also guarded by native_immediates_threadsafe_mutex_. This can be used when 1085 // trying to post tasks from other threads to an Environment, as the libuv 1086 // handle for the immediate queues (task_queues_async_) may not be initialized 1087 // yet or already have been destroyed. 1088 bool task_queues_async_initialized_ = false; 1089 1090 std::atomic<Environment**> interrupt_data_ {nullptr}; 1091 void RequestInterruptFromV8(); 1092 static void CheckImmediate(uv_check_t* handle); 1093 1094 CleanupQueue cleanup_queue_; 1095 bool started_cleanup_ = false; 1096 1097 std::unordered_set<int> unmanaged_fds_; 1098 1099 std::function<void(Environment*, int)> process_exit_handler_ { 1100 DefaultProcessExitHandler }; 1101 1102 std::unique_ptr<Realm> principal_realm_ = nullptr; 1103 1104 builtins::BuiltinLoader builtin_loader_; 1105 1106 // Used by allocate_managed_buffer() and release_managed_buffer() to keep 1107 // track of the BackingStore for a given pointer. 1108 std::unordered_map<char*, std::unique_ptr<v8::BackingStore>> 1109 released_allocated_buffers_; 1110 }; 1111 1112 } // namespace node 1113 1114 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 1115 1116 #endif // SRC_ENV_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™