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