GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: env.h Lines: 41 41 100.0 %
Date: 2022-09-25 04:23:55 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
13234
  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
22584
  ~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
11292
  ~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
11292
  ~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
6307
  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
44160
  DeserializeRequest(DeserializeRequest&& other) = default;
508
};
509
510
struct EnvSerializeInfo {
511
  std::vector<PropInfo> native_objects;
512
  std::vector<std::string> builtins;
513
  AsyncHooks::SerializeInfo async_hooks;
514
  TickInfo::SerializeInfo tick_info;
515
  ImmediateInfo::SerializeInfo immediate_info;
516
  performance::PerformanceState::SerializeInfo performance_state;
517
  AliasedBufferIndex exiting;
518
  AliasedBufferIndex stream_base_state;
519
  AliasedBufferIndex should_abort_on_uncaught_toggle;
520
521
  RealmSerializeInfo principal_realm;
522
  friend std::ostream& operator<<(std::ostream& o, const EnvSerializeInfo& i);
523
};
524
525
struct SnapshotMetadata {
526
  // For now kFullyCustomized is only built with the --build-snapshot CLI flag.
527
  // We might want to add more types of snapshots in the future.
528
  enum class Type : uint8_t { kDefault, kFullyCustomized };
529
530
  Type type;
531
  std::string node_version;
532
  std::string node_arch;
533
  std::string node_platform;
534
  // Result of v8::ScriptCompiler::CachedDataVersionTag().
535
  uint32_t v8_cache_version_tag;
536
};
537
538
struct SnapshotData {
539
  enum class DataOwnership { kOwned, kNotOwned };
540
541
  static const uint32_t kMagic = 0x143da19;
542
  static const SnapshotIndex kNodeVMContextIndex = 0;
543
  static const SnapshotIndex kNodeBaseContextIndex = kNodeVMContextIndex + 1;
544
  static const SnapshotIndex kNodeMainContextIndex = kNodeBaseContextIndex + 1;
545
546
  DataOwnership data_ownership = DataOwnership::kOwned;
547
548
  SnapshotMetadata metadata;
549
550
  // The result of v8::SnapshotCreator::CreateBlob() during the snapshot
551
  // building process.
552
  v8::StartupData v8_snapshot_blob_data{nullptr, 0};
553
554
  IsolateDataSerializeInfo isolate_data_info;
555
  // TODO(joyeecheung): there should be a vector of env_info once we snapshot
556
  // the worker environments.
557
  EnvSerializeInfo env_info;
558
559
  // A vector of built-in ids and v8::ScriptCompiler::CachedData, this can be
560
  // shared across Node.js instances because they are supposed to share the
561
  // read only space. We use builtins::CodeCacheInfo because
562
  // v8::ScriptCompiler::CachedData is not copyable.
563
  std::vector<builtins::CodeCacheInfo> code_cache;
564
565
  void ToBlob(FILE* out) const;
566
  // If returns false, the metadata doesn't match the current Node.js binary,
567
  // and the caller should not consume the snapshot data.
568
  bool Check() const;
569
  static bool FromBlob(SnapshotData* out, FILE* in);
570
571
  ~SnapshotData();
572
573
  SnapshotData(const SnapshotData&) = delete;
574
  SnapshotData& operator=(const SnapshotData&) = delete;
575
  SnapshotData(SnapshotData&&) = delete;
576
  SnapshotData& operator=(SnapshotData&&) = delete;
577
578
9
  SnapshotData() = default;
579
};
580
581
/**
582
 * Environment is a per-isolate data structure that represents an execution
583
 * environment. Each environment has a principal realm. An environment can
584
 * create multiple subsidiary synthetic realms.
585
 */
586
class Environment : public MemoryRetainer {
587
 public:
588
  Environment(const Environment&) = delete;
589
  Environment& operator=(const Environment&) = delete;
590
  Environment(Environment&&) = delete;
591
  Environment& operator=(Environment&&) = delete;
592
593
25
  SET_MEMORY_INFO_NAME(Environment)
594
595
  inline size_t SelfSize() const override;
596
50
  bool IsRootNode() const override { return true; }
597
  void MemoryInfo(MemoryTracker* tracker) const override;
598
599
  EnvSerializeInfo Serialize(v8::SnapshotCreator* creator);
600
  void DeserializeProperties(const EnvSerializeInfo* info);
601
602
  void PrintInfoForSnapshotIfDebug();
603
  void PrintAllBaseObjects();
604
  void VerifyNoStrongBaseObjects();
605
  void EnqueueDeserializeRequest(DeserializeRequestCallback cb,
606
                                 v8::Local<v8::Object> holder,
607
                                 int index,
608
                                 InternalFieldInfoBase* info);
609
  void RunDeserializeRequests();
610
  // Should be called before InitializeInspector()
611
  void InitializeDiagnostics();
612
613
  std::string GetCwd();
614
615
#if HAVE_INSPECTOR
616
  // If the environment is created for a worker, pass parent_handle and
617
  // the ownership if transferred into the Environment.
618
  int InitializeInspector(
619
      std::unique_ptr<inspector::ParentInspectorHandle> parent_handle);
620
#endif
621
622
  inline size_t async_callback_scope_depth() const;
623
  inline void PushAsyncCallbackScope();
624
  inline void PopAsyncCallbackScope();
625
626
  static inline Environment* GetCurrent(v8::Isolate* isolate);
627
  static inline Environment* GetCurrent(v8::Local<v8::Context> context);
628
  static inline Environment* GetCurrent(
629
      const v8::FunctionCallbackInfo<v8::Value>& info);
630
631
  template <typename T>
632
  static inline Environment* GetCurrent(
633
      const v8::PropertyCallbackInfo<T>& info);
634
635
  // Methods created using SetMethod(), SetPrototypeMethod(), etc. inside
636
  // this scope can access the created T* object using
637
  // GetBindingData<T>(args) later.
638
  template <typename T>
639
  T* AddBindingData(v8::Local<v8::Context> context,
640
                    v8::Local<v8::Object> target);
641
  template <typename T, typename U>
642
  static inline T* GetBindingData(const v8::PropertyCallbackInfo<U>& info);
643
  template <typename T>
644
  static inline T* GetBindingData(
645
      const v8::FunctionCallbackInfo<v8::Value>& info);
646
  template <typename T>
647
  static inline T* GetBindingData(v8::Local<v8::Context> context);
648
649
  typedef std::unordered_map<
650
      FastStringKey,
651
      BaseObjectPtr<BaseObject>,
652
      FastStringKey::Hash> BindingDataStore;
653
654
  // Create an Environment without initializing a main Context. Use
655
  // InitializeMainContext() to initialize a main context for it.
656
  Environment(IsolateData* isolate_data,
657
              v8::Isolate* isolate,
658
              const std::vector<std::string>& args,
659
              const std::vector<std::string>& exec_args,
660
              const EnvSerializeInfo* env_info,
661
              EnvironmentFlags::Flags flags,
662
              ThreadId thread_id);
663
  void InitializeMainContext(v8::Local<v8::Context> context,
664
                             const EnvSerializeInfo* env_info);
665
  // Create an Environment and initialize the provided principal context for it.
666
  Environment(IsolateData* isolate_data,
667
              v8::Local<v8::Context> context,
668
              const std::vector<std::string>& args,
669
              const std::vector<std::string>& exec_args,
670
              const EnvSerializeInfo* env_info,
671
              EnvironmentFlags::Flags flags,
672
              ThreadId thread_id);
673
  ~Environment() override;
674
675
  void InitializeLibuv();
676
  inline const std::vector<std::string>& exec_argv();
677
  inline const std::vector<std::string>& argv();
678
  const std::string& exec_path() const;
679
680
  typedef void (*HandleCleanupCb)(Environment* env,
681
                                  uv_handle_t* handle,
682
                                  void* arg);
683
  struct HandleCleanup {
684
    uv_handle_t* handle_;
685
    HandleCleanupCb cb_;
686
    void* arg_;
687
  };
688
689
  void RegisterHandleCleanups();
690
  void CleanupHandles();
691
  void Exit(int code);
692
  void ExitEnv();
693
694
  // Register clean-up cb to be called on environment destruction.
695
  inline void RegisterHandleCleanup(uv_handle_t* handle,
696
                                    HandleCleanupCb cb,
697
                                    void* arg);
698
699
  template <typename T, typename OnCloseCallback>
700
  inline void CloseHandle(T* handle, OnCloseCallback callback);
701
702
  void AssignToContext(v8::Local<v8::Context> context,
703
                       Realm* realm,
704
                       const ContextInfo& info);
705
706
  void StartProfilerIdleNotifier();
707
708
  inline v8::Isolate* isolate() const;
709
  inline uv_loop_t* event_loop() const;
710
  void TryLoadAddon(const char* filename,
711
                    int flags,
712
                    const std::function<bool(binding::DLib*)>& was_loaded);
713
714
  static inline Environment* from_timer_handle(uv_timer_t* handle);
715
  inline uv_timer_t* timer_handle();
716
717
  static inline Environment* from_immediate_check_handle(uv_check_t* handle);
718
  inline uv_check_t* immediate_check_handle();
719
  inline uv_idle_t* immediate_idle_handle();
720
721
  inline void IncreaseWaitingRequestCounter();
722
  inline void DecreaseWaitingRequestCounter();
723
724
  inline AsyncHooks* async_hooks();
725
  inline ImmediateInfo* immediate_info();
726
  inline TickInfo* tick_info();
727
  inline uint64_t timer_base() const;
728
  inline std::shared_ptr<KVStore> env_vars();
729
  inline void set_env_vars(std::shared_ptr<KVStore> env_vars);
730
731
  inline IsolateData* isolate_data() const;
732
733
  inline bool printed_error() const;
734
  inline void set_printed_error(bool value);
735
736
  void PrintSyncTrace() const;
737
  inline void set_trace_sync_io(bool value);
738
739
  inline void set_force_context_aware(bool value);
740
  inline bool force_context_aware() const;
741
742
  // This is a pseudo-boolean that keeps track of whether the process is
743
  // exiting.
744
  inline void set_exiting(bool value);
745
  inline AliasedUint32Array& exiting();
746
747
  // This stores whether the --abort-on-uncaught-exception flag was passed
748
  // to Node.
749
  inline bool abort_on_uncaught_exception() const;
750
  inline void set_abort_on_uncaught_exception(bool value);
751
  // This is a pseudo-boolean that keeps track of whether an uncaught exception
752
  // should abort the process or not if --abort-on-uncaught-exception was
753
  // passed to Node. If the flag was not passed, it is ignored.
754
  inline AliasedUint32Array& should_abort_on_uncaught_toggle();
755
756
  inline AliasedInt32Array& stream_base_state();
757
758
  // The necessary API for async_hooks.
759
  inline double new_async_id();
760
  inline double execution_async_id();
761
  inline double trigger_async_id();
762
  inline double get_default_trigger_async_id();
763
764
  // List of id's that have been destroyed and need the destroy() cb called.
765
  inline std::vector<double>* destroy_async_id_list();
766
767
  std::set<struct node_module*> internal_bindings;
768
  std::set<std::string> builtins_with_cache;
769
  std::set<std::string> builtins_without_cache;
770
  // This is only filled during deserialization. We use a vector since
771
  // it's only used for tests.
772
  std::vector<std::string> builtins_in_snapshot;
773
774
  std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map;
775
  std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map;
776
  std::unordered_map<uint32_t, contextify::ContextifyScript*>
777
      id_to_script_map;
778
  std::unordered_map<uint32_t, contextify::CompiledFnEntry*> id_to_function_map;
779
780
  inline uint32_t get_next_module_id();
781
  inline uint32_t get_next_script_id();
782
  inline uint32_t get_next_function_id();
783
784
1386866
  EnabledDebugList* enabled_debug_list() { return &enabled_debug_list_; }
785
786
  inline performance::PerformanceState* performance_state();
787
788
  void CollectUVExceptionInfo(v8::Local<v8::Value> context,
789
                              int errorno,
790
                              const char* syscall = nullptr,
791
                              const char* message = nullptr,
792
                              const char* path = nullptr,
793
                              const char* dest = nullptr);
794
795
  // If this flag is set, calls into JS (if they would be observable
796
  // from userland) must be avoided.  This flag does not indicate whether
797
  // calling into JS is allowed from a VM perspective at this point.
798
  inline bool can_call_into_js() const;
799
  inline void set_can_call_into_js(bool can_call_into_js);
800
801
  // Increase or decrease a counter that manages whether this Environment
802
  // keeps the event loop alive on its own or not. The counter starts out at 0,
803
  // meaning it does not, and any positive value will make it keep the event
804
  // loop alive.
805
  // This is used by Workers to manage their own .ref()/.unref() implementation,
806
  // as Workers aren't directly associated with their own libuv handles.
807
  void add_refs(int64_t diff);
808
809
  // Convenient getter of the principal realm's has_run_bootstrapping_code().
810
  inline bool has_run_bootstrapping_code() const;
811
812
  inline bool has_serialized_options() const;
813
  inline void set_has_serialized_options(bool has_serialized_options);
814
815
  inline bool is_main_thread() const;
816
  inline bool no_native_addons() const;
817
  inline bool should_not_register_esm_loader() const;
818
  inline bool should_create_inspector() const;
819
  inline bool owns_process_state() const;
820
  inline bool owns_inspector() const;
821
  inline bool tracks_unmanaged_fds() const;
822
  inline bool hide_console_windows() const;
823
  inline bool no_global_search_paths() const;
824
  inline bool no_browser_globals() const;
825
  inline uint64_t thread_id() const;
826
  inline worker::Worker* worker_context() const;
827
  Environment* worker_parent_env() const;
828
  inline void add_sub_worker_context(worker::Worker* context);
829
  inline void remove_sub_worker_context(worker::Worker* context);
830
  void stop_sub_worker_contexts();
831
  template <typename Fn>
832
  inline void ForEachWorker(Fn&& iterator);
833
  inline bool is_stopping() const;
834
  inline void set_stopping(bool value);
835
  inline std::list<node_module>* extra_linked_bindings();
836
  inline node_module* extra_linked_bindings_head();
837
  inline node_module* extra_linked_bindings_tail();
838
  inline const Mutex& extra_linked_bindings_mutex() const;
839
840
  inline bool filehandle_close_warning() const;
841
  inline void set_filehandle_close_warning(bool on);
842
843
  inline void set_source_maps_enabled(bool on);
844
  inline bool source_maps_enabled() const;
845
846
  inline void ThrowError(const char* errmsg);
847
  inline void ThrowTypeError(const char* errmsg);
848
  inline void ThrowRangeError(const char* errmsg);
849
  inline void ThrowErrnoException(int errorno,
850
                                  const char* syscall = nullptr,
851
                                  const char* message = nullptr,
852
                                  const char* path = nullptr);
853
  inline void ThrowUVException(int errorno,
854
                               const char* syscall = nullptr,
855
                               const char* message = nullptr,
856
                               const char* path = nullptr,
857
                               const char* dest = nullptr);
858
859
  void AtExit(void (*cb)(void* arg), void* arg);
860
  void RunAtExitCallbacks();
861
862
  void RunWeakRefCleanup();
863
864
  v8::MaybeLocal<v8::Value> RunSnapshotSerializeCallback() const;
865
  v8::MaybeLocal<v8::Value> RunSnapshotDeserializeCallback() const;
866
  v8::MaybeLocal<v8::Value> RunSnapshotDeserializeMain() const;
867
868
  // Primitive values are shared across realms.
869
  // The getters simply proxy to the per-isolate primitive.
870
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
871
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
872
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
873
#define V(TypeName, PropertyName)                                             \
874
  inline v8::Local<TypeName> PropertyName() const;
875
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
876
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
877
  PER_ISOLATE_STRING_PROPERTIES(VS)
878
#undef V
879
#undef VS
880
#undef VY
881
#undef VP
882
883
#define V(PropertyName, TypeName)                                             \
884
  inline v8::Local<TypeName> PropertyName() const;                            \
885
  inline void set_ ## PropertyName(v8::Local<TypeName> value);
886
  PER_ISOLATE_TEMPLATE_PROPERTIES(V)
887
  // Per-realm strong persistent values of the principal realm.
888
  // Get/set the value with an explicit realm instead when possible.
889
  // Deprecate soon.
890
  PER_REALM_STRONG_PERSISTENT_VALUES(V)
891
#undef V
892
893
  // Return the context of the principal realm.
894
  // Get the context with an explicit realm instead when possible.
895
  // Deprecate soon.
896
  inline v8::Local<v8::Context> context() const;
897
  inline Realm* principal_realm() const;
898
899
#if HAVE_INSPECTOR
900
105075
  inline inspector::Agent* inspector_agent() const {
901
105075
    return inspector_agent_.get();
902
  }
903
904
  inline bool is_in_inspector_console_call() const;
905
  inline void set_is_in_inspector_console_call(bool value);
906
#endif
907
908
  typedef ListHead<HandleWrap, &HandleWrap::handle_wrap_queue_> HandleWrapQueue;
909
  typedef ListHead<ReqWrapBase, &ReqWrapBase::req_wrap_queue_> ReqWrapQueue;
910
911
65526
  inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; }
912
84120
  inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; }
913
914
7072
  inline uint64_t time_origin() {
915
7072
    return time_origin_;
916
  }
917
7056
  inline double time_origin_timestamp() {
918
7056
    return time_origin_timestamp_;
919
  }
920
921
1
  inline bool EmitProcessEnvWarning() {
922
1
    bool current_value = emit_env_nonstring_warning_;
923
1
    emit_env_nonstring_warning_ = false;
924
1
    return current_value;
925
  }
926
927
1
  inline bool EmitErrNameWarning() {
928
1
    bool current_value = emit_err_name_warning_;
929
1
    emit_err_name_warning_ = false;
930
1
    return current_value;
931
  }
932
933
  // cb will be called as cb(env) on the next event loop iteration.
934
  // Unlike the JS setImmediate() function, nested SetImmediate() calls will
935
  // be run without returning control to the event loop, similar to nextTick().
936
  template <typename Fn>
937
  inline void SetImmediate(
938
      Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed);
939
  template <typename Fn>
940
  // This behaves like SetImmediate() but can be called from any thread.
941
  inline void SetImmediateThreadsafe(
942
      Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed);
943
  // This behaves like V8's Isolate::RequestInterrupt(), but also accounts for
944
  // the event loop (i.e. combines the V8 function with SetImmediate()).
945
  // The passed callback may not throw exceptions.
946
  // This function can be called from any thread.
947
  template <typename Fn>
948
  inline void RequestInterrupt(Fn&& cb);
949
  // This needs to be available for the JS-land setImmediate().
950
  void ToggleImmediateRef(bool ref);
951
952
  inline void PushShouldNotAbortOnUncaughtScope();
953
  inline void PopShouldNotAbortOnUncaughtScope();
954
  inline bool inside_should_not_abort_on_uncaught_scope() const;
955
956
  static inline Environment* ForAsyncHooks(AsyncHooks* hooks);
957
958
  v8::Local<v8::Value> GetNow();
959
  void ScheduleTimer(int64_t duration);
960
  void ToggleTimerRef(bool ref);
961
962
  inline void AddCleanupHook(CleanupQueue::Callback cb, void* arg);
963
  inline void RemoveCleanupHook(CleanupQueue::Callback cb, void* arg);
964
  void RunCleanup();
965
966
  static size_t NearHeapLimitCallback(void* data,
967
                                      size_t current_heap_limit,
968
                                      size_t initial_heap_limit);
969
  static void BuildEmbedderGraph(v8::Isolate* isolate,
970
                                 v8::EmbedderGraph* graph,
971
                                 void* data);
972
973
  inline std::shared_ptr<EnvironmentOptions> options();
974
  inline std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port();
975
976
  // The BaseObject count is a debugging helper that makes sure that there are
977
  // no memory leaks caused by BaseObjects staying alive longer than expected
978
  // (in particular, no circular BaseObjectPtr references).
979
  inline void modify_base_object_count(int64_t delta);
980
  inline int64_t base_object_count() const;
981
982
  // Base object count created in bootstrap of the principal realm.
983
  // This adjusts the return value of base_object_created_after_bootstrap() so
984
  // that tests that check the count do not have to account for internally
985
  // created BaseObjects.
986
  inline void set_base_object_created_by_bootstrap(int64_t count);
987
  inline int64_t base_object_created_after_bootstrap() const;
988
989
3
  inline int32_t stack_trace_limit() const { return 10; }
990
991
#if HAVE_INSPECTOR
992
  void set_coverage_connection(
993
      std::unique_ptr<profiler::V8CoverageConnection> connection);
994
  profiler::V8CoverageConnection* coverage_connection();
995
996
  inline void set_coverage_directory(const char* directory);
997
  inline const std::string& coverage_directory() const;
998
999
  void set_cpu_profiler_connection(
1000
      std::unique_ptr<profiler::V8CpuProfilerConnection> connection);
1001
  profiler::V8CpuProfilerConnection* cpu_profiler_connection();
1002
1003
  inline void set_cpu_prof_name(const std::string& name);
1004
  inline const std::string& cpu_prof_name() const;
1005
1006
  inline void set_cpu_prof_interval(uint64_t interval);
1007
  inline uint64_t cpu_prof_interval() const;
1008
1009
  inline void set_cpu_prof_dir(const std::string& dir);
1010
  inline const std::string& cpu_prof_dir() const;
1011
1012
  void set_heap_profiler_connection(
1013
      std::unique_ptr<profiler::V8HeapProfilerConnection> connection);
1014
  profiler::V8HeapProfilerConnection* heap_profiler_connection();
1015
1016
  inline void set_heap_prof_name(const std::string& name);
1017
  inline const std::string& heap_prof_name() const;
1018
1019
  inline void set_heap_prof_dir(const std::string& dir);
1020
  inline const std::string& heap_prof_dir() const;
1021
1022
  inline void set_heap_prof_interval(uint64_t interval);
1023
  inline uint64_t heap_prof_interval() const;
1024
1025
#endif  // HAVE_INSPECTOR
1026
1027
  inline void set_main_utf16(std::unique_ptr<v8::String::Value>);
1028
  inline void set_process_exit_handler(
1029
      std::function<void(Environment*, int)>&& handler);
1030
1031
  void RunAndClearNativeImmediates(bool only_refed = false);
1032
  void RunAndClearInterrupts();
1033
1034
  uv_buf_t allocate_managed_buffer(const size_t suggested_size);
1035
  std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf);
1036
1037
  void AddUnmanagedFd(int fd);
1038
  void RemoveUnmanagedFd(int fd);
1039
1040
  template <typename T>
1041
  void ForEachBaseObject(T&& iterator);
1042
1043
  inline void set_heap_snapshot_near_heap_limit(uint32_t limit);
1044
  inline bool is_in_heapsnapshot_heap_limit_callback() const;
1045
1046
  inline void AddHeapSnapshotNearHeapLimitCallback();
1047
1048
  inline void RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit);
1049
1050
 private:
1051
  inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
1052
                         const char* errmsg);
1053
1054
  std::list<binding::DLib> loaded_addons_;
1055
  v8::Isolate* const isolate_;
1056
  IsolateData* const isolate_data_;
1057
  uv_timer_t timer_handle_;
1058
  uv_check_t immediate_check_handle_;
1059
  uv_idle_t immediate_idle_handle_;
1060
  uv_prepare_t idle_prepare_handle_;
1061
  uv_check_t idle_check_handle_;
1062
  uv_async_t task_queues_async_;
1063
  int64_t task_queues_async_refs_ = 0;
1064
1065
  AsyncHooks async_hooks_;
1066
  ImmediateInfo immediate_info_;
1067
  TickInfo tick_info_;
1068
  const uint64_t timer_base_;
1069
  std::shared_ptr<KVStore> env_vars_;
1070
  bool printed_error_ = false;
1071
  bool trace_sync_io_ = false;
1072
  bool emit_env_nonstring_warning_ = true;
1073
  bool emit_err_name_warning_ = true;
1074
  bool emit_filehandle_warning_ = true;
1075
  bool source_maps_enabled_ = false;
1076
1077
  size_t async_callback_scope_depth_ = 0;
1078
  std::vector<double> destroy_async_id_list_;
1079
1080
#if HAVE_INSPECTOR
1081
  std::unique_ptr<profiler::V8CoverageConnection> coverage_connection_;
1082
  std::unique_ptr<profiler::V8CpuProfilerConnection> cpu_profiler_connection_;
1083
  std::string coverage_directory_;
1084
  std::string cpu_prof_dir_;
1085
  std::string cpu_prof_name_;
1086
  uint64_t cpu_prof_interval_;
1087
  std::unique_ptr<profiler::V8HeapProfilerConnection> heap_profiler_connection_;
1088
  std::string heap_prof_dir_;
1089
  std::string heap_prof_name_;
1090
  uint64_t heap_prof_interval_;
1091
#endif  // HAVE_INSPECTOR
1092
1093
  std::shared_ptr<EnvironmentOptions> options_;
1094
  // options_ contains debug options parsed from CLI arguments,
1095
  // while inspector_host_port_ stores the actual inspector host
1096
  // and port being used. For example the port is -1 by default
1097
  // and can be specified as 0 (meaning any port allocated when the
1098
  // server starts listening), but when the inspector server starts
1099
  // the inspector_host_port_->port() will be the actual port being
1100
  // used.
1101
  std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port_;
1102
  std::vector<std::string> exec_argv_;
1103
  std::vector<std::string> argv_;
1104
  std::string exec_path_;
1105
1106
  bool is_in_heapsnapshot_heap_limit_callback_ = false;
1107
  uint32_t heap_limit_snapshot_taken_ = 0;
1108
  uint32_t heap_snapshot_near_heap_limit_ = 0;
1109
  bool heapsnapshot_near_heap_limit_callback_added_ = false;
1110
1111
  uint32_t module_id_counter_ = 0;
1112
  uint32_t script_id_counter_ = 0;
1113
  uint32_t function_id_counter_ = 0;
1114
1115
  AliasedUint32Array exiting_;
1116
1117
  AliasedUint32Array should_abort_on_uncaught_toggle_;
1118
  int should_not_abort_scope_counter_ = 0;
1119
1120
  std::unique_ptr<TrackingTraceStateObserver> trace_state_observer_;
1121
1122
  AliasedInt32Array stream_base_state_;
1123
1124
  // https://w3c.github.io/hr-time/#dfn-time-origin
1125
  uint64_t time_origin_;
1126
  // https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp
1127
  double time_origin_timestamp_;
1128
  std::unique_ptr<performance::PerformanceState> performance_state_;
1129
1130
  bool has_serialized_options_ = false;
1131
1132
  std::atomic_bool can_call_into_js_ { true };
1133
  uint64_t flags_;
1134
  uint64_t thread_id_;
1135
  std::unordered_set<worker::Worker*> sub_worker_contexts_;
1136
1137
#if HAVE_INSPECTOR
1138
  std::unique_ptr<inspector::Agent> inspector_agent_;
1139
  bool is_in_inspector_console_call_ = false;
1140
#endif
1141
1142
  std::list<DeserializeRequest> deserialize_requests_;
1143
1144
  // handle_wrap_queue_ and req_wrap_queue_ needs to be at a fixed offset from
1145
  // the start of the class because it is used by
1146
  // src/node_postmortem_metadata.cc to calculate offsets and generate debug
1147
  // symbols for Environment, which assumes that the position of members in
1148
  // memory are predictable. For more information please refer to
1149
  // `doc/contributing/node-postmortem-support.md`
1150
  friend int GenDebugSymbols();
1151
  HandleWrapQueue handle_wrap_queue_;
1152
  ReqWrapQueue req_wrap_queue_;
1153
  std::list<HandleCleanup> handle_cleanup_queue_;
1154
  int handle_cleanup_waiting_ = 0;
1155
  int request_waiting_ = 0;
1156
1157
  EnabledDebugList enabled_debug_list_;
1158
1159
  std::list<node_module> extra_linked_bindings_;
1160
  Mutex extra_linked_bindings_mutex_;
1161
1162
  static void RunTimers(uv_timer_t* handle);
1163
1164
  struct ExitCallback {
1165
    void (*cb_)(void* arg);
1166
    void* arg_;
1167
  };
1168
1169
  std::list<ExitCallback> at_exit_functions_;
1170
1171
  typedef CallbackQueue<void, Environment*> NativeImmediateQueue;
1172
  NativeImmediateQueue native_immediates_;
1173
  Mutex native_immediates_threadsafe_mutex_;
1174
  NativeImmediateQueue native_immediates_threadsafe_;
1175
  NativeImmediateQueue native_immediates_interrupts_;
1176
  // Also guarded by native_immediates_threadsafe_mutex_. This can be used when
1177
  // trying to post tasks from other threads to an Environment, as the libuv
1178
  // handle for the immediate queues (task_queues_async_) may not be initialized
1179
  // yet or already have been destroyed.
1180
  bool task_queues_async_initialized_ = false;
1181
1182
  std::atomic<Environment**> interrupt_data_ {nullptr};
1183
  void RequestInterruptFromV8();
1184
  static void CheckImmediate(uv_check_t* handle);
1185
1186
  BindingDataStore bindings_;
1187
1188
  CleanupQueue cleanup_queue_;
1189
  bool started_cleanup_ = false;
1190
1191
  int64_t base_object_count_ = 0;
1192
  int64_t base_object_created_by_bootstrap_ = 0;
1193
  std::atomic_bool is_stopping_ { false };
1194
1195
  std::unordered_set<int> unmanaged_fds_;
1196
1197
  std::function<void(Environment*, int)> process_exit_handler_ {
1198
      DefaultProcessExitHandler };
1199
1200
  std::unique_ptr<Realm> principal_realm_ = nullptr;
1201
1202
  // Keeps the main script source alive is one was passed to LoadEnvironment().
1203
  // We should probably find a way to just use plain `v8::String`s created from
1204
  // the source passed to LoadEnvironment() directly instead.
1205
  std::unique_ptr<v8::String::Value> main_utf16_;
1206
1207
  // Used by allocate_managed_buffer() and release_managed_buffer() to keep
1208
  // track of the BackingStore for a given pointer.
1209
  std::unordered_map<char*, std::unique_ptr<v8::BackingStore>>
1210
      released_allocated_buffers_;
1211
};
1212
1213
}  // namespace node
1214
1215
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1216
1217
#endif  // SRC_ENV_H_