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