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