GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: env.h Lines: 41 41 100.0 %
Date: 2022-11-10 04:21:28 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
37
  SET_MEMORY_INFO_NAME(IsolateData)
176
37
  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
13382
  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
37
  SET_MEMORY_INFO_NAME(AsyncHooks)
270
37
  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
22760
  ~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
11380
  ~ImmediateInfo() = default;
405
406
37
  SET_MEMORY_INFO_NAME(ImmediateInfo)
407
37
  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
37
  SET_MEMORY_INFO_NAME(TickInfo)
433
37
  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
11380
  ~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
6380
  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
44744
  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 exit_info;
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
37
  SET_MEMORY_INFO_NAME(Environment)
594
595
  inline size_t SelfSize() const override;
596
68
  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 contains fields that are a pseudo-boolean that keeps track of whether
747
  // the process is exiting, an integer representing the process exit code, and
748
  // a pseudo-boolean to indicate whether the exit code is undefined.
749
  inline AliasedInt32Array& exit_info();
750
  inline void set_exiting(bool value);
751
  inline ExitCode exit_code(const ExitCode default_code) const;
752
753
  // This stores whether the --abort-on-uncaught-exception flag was passed
754
  // to Node.
755
  inline bool abort_on_uncaught_exception() const;
756
  inline void set_abort_on_uncaught_exception(bool value);
757
  // This is a pseudo-boolean that keeps track of whether an uncaught exception
758
  // should abort the process or not if --abort-on-uncaught-exception was
759
  // passed to Node. If the flag was not passed, it is ignored.
760
  inline AliasedUint32Array& should_abort_on_uncaught_toggle();
761
762
  inline AliasedInt32Array& stream_base_state();
763
764
  // The necessary API for async_hooks.
765
  inline double new_async_id();
766
  inline double execution_async_id();
767
  inline double trigger_async_id();
768
  inline double get_default_trigger_async_id();
769
770
  // List of id's that have been destroyed and need the destroy() cb called.
771
  inline std::vector<double>* destroy_async_id_list();
772
773
  std::set<struct node_module*> internal_bindings;
774
  std::set<std::string> builtins_with_cache;
775
  std::set<std::string> builtins_without_cache;
776
  // This is only filled during deserialization. We use a vector since
777
  // it's only used for tests.
778
  std::vector<std::string> builtins_in_snapshot;
779
780
  std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map;
781
  std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map;
782
  std::unordered_map<uint32_t, contextify::ContextifyScript*>
783
      id_to_script_map;
784
  std::unordered_map<uint32_t, contextify::CompiledFnEntry*> id_to_function_map;
785
786
  inline uint32_t get_next_module_id();
787
  inline uint32_t get_next_script_id();
788
  inline uint32_t get_next_function_id();
789
790
1405191
  EnabledDebugList* enabled_debug_list() { return &enabled_debug_list_; }
791
792
  inline performance::PerformanceState* performance_state();
793
794
  void CollectUVExceptionInfo(v8::Local<v8::Value> context,
795
                              int errorno,
796
                              const char* syscall = nullptr,
797
                              const char* message = nullptr,
798
                              const char* path = nullptr,
799
                              const char* dest = nullptr);
800
801
  // If this flag is set, calls into JS (if they would be observable
802
  // from userland) must be avoided.  This flag does not indicate whether
803
  // calling into JS is allowed from a VM perspective at this point.
804
  inline bool can_call_into_js() const;
805
  inline void set_can_call_into_js(bool can_call_into_js);
806
807
  // Increase or decrease a counter that manages whether this Environment
808
  // keeps the event loop alive on its own or not. The counter starts out at 0,
809
  // meaning it does not, and any positive value will make it keep the event
810
  // loop alive.
811
  // This is used by Workers to manage their own .ref()/.unref() implementation,
812
  // as Workers aren't directly associated with their own libuv handles.
813
  void add_refs(int64_t diff);
814
815
  // Convenient getter of the principal realm's has_run_bootstrapping_code().
816
  inline bool has_run_bootstrapping_code() const;
817
818
  inline bool has_serialized_options() const;
819
  inline void set_has_serialized_options(bool has_serialized_options);
820
821
  inline bool is_main_thread() const;
822
  inline bool no_native_addons() const;
823
  inline bool should_not_register_esm_loader() const;
824
  inline bool should_create_inspector() const;
825
  inline bool owns_process_state() const;
826
  inline bool owns_inspector() const;
827
  inline bool tracks_unmanaged_fds() const;
828
  inline bool hide_console_windows() const;
829
  inline bool no_global_search_paths() const;
830
  inline bool no_browser_globals() const;
831
  inline uint64_t thread_id() const;
832
  inline worker::Worker* worker_context() const;
833
  Environment* worker_parent_env() const;
834
  inline void add_sub_worker_context(worker::Worker* context);
835
  inline void remove_sub_worker_context(worker::Worker* context);
836
  void stop_sub_worker_contexts();
837
  template <typename Fn>
838
  inline void ForEachWorker(Fn&& iterator);
839
  inline bool is_stopping() const;
840
  inline void set_stopping(bool value);
841
  inline std::list<node_module>* extra_linked_bindings();
842
  inline node_module* extra_linked_bindings_head();
843
  inline node_module* extra_linked_bindings_tail();
844
  inline const Mutex& extra_linked_bindings_mutex() const;
845
846
  inline bool filehandle_close_warning() const;
847
  inline void set_filehandle_close_warning(bool on);
848
849
  inline void set_source_maps_enabled(bool on);
850
  inline bool source_maps_enabled() const;
851
852
  inline void ThrowError(const char* errmsg);
853
  inline void ThrowTypeError(const char* errmsg);
854
  inline void ThrowRangeError(const char* errmsg);
855
  inline void ThrowErrnoException(int errorno,
856
                                  const char* syscall = nullptr,
857
                                  const char* message = nullptr,
858
                                  const char* path = nullptr);
859
  inline void ThrowUVException(int errorno,
860
                               const char* syscall = nullptr,
861
                               const char* message = nullptr,
862
                               const char* path = nullptr,
863
                               const char* dest = nullptr);
864
865
  void AtExit(void (*cb)(void* arg), void* arg);
866
  void RunAtExitCallbacks();
867
868
  void RunWeakRefCleanup();
869
870
  v8::MaybeLocal<v8::Value> RunSnapshotSerializeCallback() const;
871
  v8::MaybeLocal<v8::Value> RunSnapshotDeserializeCallback() const;
872
  v8::MaybeLocal<v8::Value> RunSnapshotDeserializeMain() const;
873
874
  // Primitive values are shared across realms.
875
  // The getters simply proxy to the per-isolate primitive.
876
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
877
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
878
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
879
#define V(TypeName, PropertyName)                                             \
880
  inline v8::Local<TypeName> PropertyName() const;
881
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
882
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
883
  PER_ISOLATE_STRING_PROPERTIES(VS)
884
#undef V
885
#undef VS
886
#undef VY
887
#undef VP
888
889
#define V(PropertyName, TypeName)                                             \
890
  inline v8::Local<TypeName> PropertyName() const;                            \
891
  inline void set_ ## PropertyName(v8::Local<TypeName> value);
892
  PER_ISOLATE_TEMPLATE_PROPERTIES(V)
893
  // Per-realm strong persistent values of the principal realm.
894
  // Get/set the value with an explicit realm instead when possible.
895
  // Deprecate soon.
896
  PER_REALM_STRONG_PERSISTENT_VALUES(V)
897
#undef V
898
899
  // Return the context of the principal realm.
900
  // Get the context with an explicit realm instead when possible.
901
  // Deprecate soon.
902
  inline v8::Local<v8::Context> context() const;
903
  inline Realm* principal_realm() const;
904
905
#if HAVE_INSPECTOR
906
107092
  inline inspector::Agent* inspector_agent() const {
907
107092
    return inspector_agent_.get();
908
  }
909
910
  inline bool is_in_inspector_console_call() const;
911
  inline void set_is_in_inspector_console_call(bool value);
912
#endif
913
914
  typedef ListHead<HandleWrap, &HandleWrap::handle_wrap_queue_> HandleWrapQueue;
915
  typedef ListHead<ReqWrapBase, &ReqWrapBase::req_wrap_queue_> ReqWrapQueue;
916
917
65646
  inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; }
918
84990
  inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; }
919
920
7150
  inline uint64_t time_origin() {
921
7150
    return time_origin_;
922
  }
923
8
  inline double time_origin_timestamp() {
924
8
    return time_origin_timestamp_;
925
  }
926
927
1
  inline bool EmitProcessEnvWarning() {
928
1
    bool current_value = emit_env_nonstring_warning_;
929
1
    emit_env_nonstring_warning_ = false;
930
1
    return current_value;
931
  }
932
933
1
  inline bool EmitErrNameWarning() {
934
1
    bool current_value = emit_err_name_warning_;
935
1
    emit_err_name_warning_ = false;
936
1
    return current_value;
937
  }
938
939
  // cb will be called as cb(env) on the next event loop iteration.
940
  // Unlike the JS setImmediate() function, nested SetImmediate() calls will
941
  // be run without returning control to the event loop, similar to nextTick().
942
  template <typename Fn>
943
  inline void SetImmediate(
944
      Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed);
945
  template <typename Fn>
946
  // This behaves like SetImmediate() but can be called from any thread.
947
  inline void SetImmediateThreadsafe(
948
      Fn&& cb, CallbackFlags::Flags flags = CallbackFlags::kRefed);
949
  // This behaves like V8's Isolate::RequestInterrupt(), but also accounts for
950
  // the event loop (i.e. combines the V8 function with SetImmediate()).
951
  // The passed callback may not throw exceptions.
952
  // This function can be called from any thread.
953
  template <typename Fn>
954
  inline void RequestInterrupt(Fn&& cb);
955
  // This needs to be available for the JS-land setImmediate().
956
  void ToggleImmediateRef(bool ref);
957
958
  inline void PushShouldNotAbortOnUncaughtScope();
959
  inline void PopShouldNotAbortOnUncaughtScope();
960
  inline bool inside_should_not_abort_on_uncaught_scope() const;
961
962
  static inline Environment* ForAsyncHooks(AsyncHooks* hooks);
963
964
  v8::Local<v8::Value> GetNow();
965
  void ScheduleTimer(int64_t duration);
966
  void ToggleTimerRef(bool ref);
967
968
  inline void AddCleanupHook(CleanupQueue::Callback cb, void* arg);
969
  inline void RemoveCleanupHook(CleanupQueue::Callback cb, void* arg);
970
  void RunCleanup();
971
972
  static size_t NearHeapLimitCallback(void* data,
973
                                      size_t current_heap_limit,
974
                                      size_t initial_heap_limit);
975
  static void BuildEmbedderGraph(v8::Isolate* isolate,
976
                                 v8::EmbedderGraph* graph,
977
                                 void* data);
978
979
  inline std::shared_ptr<EnvironmentOptions> options();
980
  inline std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port();
981
982
3
  inline int32_t stack_trace_limit() const { return 10; }
983
984
#if HAVE_INSPECTOR
985
  void set_coverage_connection(
986
      std::unique_ptr<profiler::V8CoverageConnection> connection);
987
  profiler::V8CoverageConnection* coverage_connection();
988
989
  inline void set_coverage_directory(const char* directory);
990
  inline const std::string& coverage_directory() const;
991
992
  void set_cpu_profiler_connection(
993
      std::unique_ptr<profiler::V8CpuProfilerConnection> connection);
994
  profiler::V8CpuProfilerConnection* cpu_profiler_connection();
995
996
  inline void set_cpu_prof_name(const std::string& name);
997
  inline const std::string& cpu_prof_name() const;
998
999
  inline void set_cpu_prof_interval(uint64_t interval);
1000
  inline uint64_t cpu_prof_interval() const;
1001
1002
  inline void set_cpu_prof_dir(const std::string& dir);
1003
  inline const std::string& cpu_prof_dir() const;
1004
1005
  void set_heap_profiler_connection(
1006
      std::unique_ptr<profiler::V8HeapProfilerConnection> connection);
1007
  profiler::V8HeapProfilerConnection* heap_profiler_connection();
1008
1009
  inline void set_heap_prof_name(const std::string& name);
1010
  inline const std::string& heap_prof_name() const;
1011
1012
  inline void set_heap_prof_dir(const std::string& dir);
1013
  inline const std::string& heap_prof_dir() const;
1014
1015
  inline void set_heap_prof_interval(uint64_t interval);
1016
  inline uint64_t heap_prof_interval() const;
1017
1018
#endif  // HAVE_INSPECTOR
1019
1020
  inline void set_main_utf16(std::unique_ptr<v8::String::Value>);
1021
  inline void set_process_exit_handler(
1022
      std::function<void(Environment*, ExitCode)>&& handler);
1023
1024
  void RunAndClearNativeImmediates(bool only_refed = false);
1025
  void RunAndClearInterrupts();
1026
1027
  uv_buf_t allocate_managed_buffer(const size_t suggested_size);
1028
  std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf);
1029
1030
  void AddUnmanagedFd(int fd);
1031
  void RemoveUnmanagedFd(int fd);
1032
1033
  template <typename T>
1034
  void ForEachRealm(T&& iterator) const;
1035
1036
  inline void set_heap_snapshot_near_heap_limit(uint32_t limit);
1037
  inline bool is_in_heapsnapshot_heap_limit_callback() const;
1038
1039
  inline void AddHeapSnapshotNearHeapLimitCallback();
1040
1041
  inline void RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit);
1042
1043
  // Field identifiers for exit_info_
1044
  enum ExitInfoField {
1045
    kExiting = 0,
1046
    kExitCode,
1047
    kHasExitCode,
1048
    kExitInfoFieldCount
1049
  };
1050
1051
 private:
1052
  inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
1053
                         const char* errmsg);
1054
1055
  std::list<binding::DLib> loaded_addons_;
1056
  v8::Isolate* const isolate_;
1057
  IsolateData* const isolate_data_;
1058
  uv_timer_t timer_handle_;
1059
  uv_check_t immediate_check_handle_;
1060
  uv_idle_t immediate_idle_handle_;
1061
  uv_prepare_t idle_prepare_handle_;
1062
  uv_check_t idle_check_handle_;
1063
  uv_async_t task_queues_async_;
1064
  int64_t task_queues_async_refs_ = 0;
1065
1066
  AsyncHooks async_hooks_;
1067
  ImmediateInfo immediate_info_;
1068
  TickInfo tick_info_;
1069
  const uint64_t timer_base_;
1070
  std::shared_ptr<KVStore> env_vars_;
1071
  bool printed_error_ = false;
1072
  bool trace_sync_io_ = false;
1073
  bool emit_env_nonstring_warning_ = true;
1074
  bool emit_err_name_warning_ = true;
1075
  bool emit_filehandle_warning_ = true;
1076
  bool source_maps_enabled_ = false;
1077
1078
  size_t async_callback_scope_depth_ = 0;
1079
  std::vector<double> destroy_async_id_list_;
1080
1081
#if HAVE_INSPECTOR
1082
  std::unique_ptr<profiler::V8CoverageConnection> coverage_connection_;
1083
  std::unique_ptr<profiler::V8CpuProfilerConnection> cpu_profiler_connection_;
1084
  std::string coverage_directory_;
1085
  std::string cpu_prof_dir_;
1086
  std::string cpu_prof_name_;
1087
  uint64_t cpu_prof_interval_;
1088
  std::unique_ptr<profiler::V8HeapProfilerConnection> heap_profiler_connection_;
1089
  std::string heap_prof_dir_;
1090
  std::string heap_prof_name_;
1091
  uint64_t heap_prof_interval_;
1092
#endif  // HAVE_INSPECTOR
1093
1094
  std::shared_ptr<EnvironmentOptions> options_;
1095
  // options_ contains debug options parsed from CLI arguments,
1096
  // while inspector_host_port_ stores the actual inspector host
1097
  // and port being used. For example the port is -1 by default
1098
  // and can be specified as 0 (meaning any port allocated when the
1099
  // server starts listening), but when the inspector server starts
1100
  // the inspector_host_port_->port() will be the actual port being
1101
  // used.
1102
  std::shared_ptr<ExclusiveAccess<HostPort>> inspector_host_port_;
1103
  std::vector<std::string> exec_argv_;
1104
  std::vector<std::string> argv_;
1105
  std::string exec_path_;
1106
1107
  bool is_in_heapsnapshot_heap_limit_callback_ = false;
1108
  uint32_t heap_limit_snapshot_taken_ = 0;
1109
  uint32_t heap_snapshot_near_heap_limit_ = 0;
1110
  bool heapsnapshot_near_heap_limit_callback_added_ = false;
1111
1112
  uint32_t module_id_counter_ = 0;
1113
  uint32_t script_id_counter_ = 0;
1114
  uint32_t function_id_counter_ = 0;
1115
1116
  AliasedInt32Array exit_info_;
1117
1118
  AliasedUint32Array should_abort_on_uncaught_toggle_;
1119
  int should_not_abort_scope_counter_ = 0;
1120
1121
  std::unique_ptr<TrackingTraceStateObserver> trace_state_observer_;
1122
1123
  AliasedInt32Array stream_base_state_;
1124
1125
  // https://w3c.github.io/hr-time/#dfn-time-origin
1126
  uint64_t time_origin_;
1127
  // https://w3c.github.io/hr-time/#dfn-get-time-origin-timestamp
1128
  double time_origin_timestamp_;
1129
  std::unique_ptr<performance::PerformanceState> performance_state_;
1130
1131
  bool has_serialized_options_ = false;
1132
1133
  std::atomic_bool can_call_into_js_ { true };
1134
  uint64_t flags_;
1135
  uint64_t thread_id_;
1136
  std::unordered_set<worker::Worker*> sub_worker_contexts_;
1137
1138
#if HAVE_INSPECTOR
1139
  std::unique_ptr<inspector::Agent> inspector_agent_;
1140
  bool is_in_inspector_console_call_ = false;
1141
#endif
1142
1143
  std::list<DeserializeRequest> deserialize_requests_;
1144
1145
  // handle_wrap_queue_ and req_wrap_queue_ needs to be at a fixed offset from
1146
  // the start of the class because it is used by
1147
  // src/node_postmortem_metadata.cc to calculate offsets and generate debug
1148
  // symbols for Environment, which assumes that the position of members in
1149
  // memory are predictable. For more information please refer to
1150
  // `doc/contributing/node-postmortem-support.md`
1151
  friend int GenDebugSymbols();
1152
  HandleWrapQueue handle_wrap_queue_;
1153
  ReqWrapQueue req_wrap_queue_;
1154
  std::list<HandleCleanup> handle_cleanup_queue_;
1155
  int handle_cleanup_waiting_ = 0;
1156
  int request_waiting_ = 0;
1157
1158
  EnabledDebugList enabled_debug_list_;
1159
1160
  std::vector<v8::Global<v8::Context>> contexts_;
1161
  std::list<node_module> extra_linked_bindings_;
1162
  Mutex extra_linked_bindings_mutex_;
1163
1164
  static void RunTimers(uv_timer_t* handle);
1165
1166
  struct ExitCallback {
1167
    void (*cb_)(void* arg);
1168
    void* arg_;
1169
  };
1170
1171
  std::list<ExitCallback> at_exit_functions_;
1172
1173
  typedef CallbackQueue<void, Environment*> NativeImmediateQueue;
1174
  NativeImmediateQueue native_immediates_;
1175
  Mutex native_immediates_threadsafe_mutex_;
1176
  NativeImmediateQueue native_immediates_threadsafe_;
1177
  NativeImmediateQueue native_immediates_interrupts_;
1178
  // Also guarded by native_immediates_threadsafe_mutex_. This can be used when
1179
  // trying to post tasks from other threads to an Environment, as the libuv
1180
  // handle for the immediate queues (task_queues_async_) may not be initialized
1181
  // yet or already have been destroyed.
1182
  bool task_queues_async_initialized_ = false;
1183
1184
  std::atomic<Environment**> interrupt_data_ {nullptr};
1185
  void RequestInterruptFromV8();
1186
  static void CheckImmediate(uv_check_t* handle);
1187
1188
  BindingDataStore bindings_;
1189
1190
  CleanupQueue cleanup_queue_;
1191
  bool started_cleanup_ = false;
1192
1193
  std::atomic_bool is_stopping_ { false };
1194
1195
  std::unordered_set<int> unmanaged_fds_;
1196
1197
  std::function<void(Environment*, ExitCode)> process_exit_handler_{
1198
      DefaultProcessExitHandlerInternal};
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_