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