GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: env.h Lines: 41 41 100.0 %
Date: 2022-11-20 04:28:36 Branches: 1 2 50.0 %

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