GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: env.h Lines: 41 41 100.0 %
Date: 2022-09-29 04:23:51 Branches: 1 2 50.0 %

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