GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/env-inl.h Lines: 672 684 98.2 %
Date: 2021-06-03 04:12:28 Branches: 124 186 66.7 %

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_INL_H_
23
#define SRC_ENV_INL_H_
24
25
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26
27
#include "aliased_buffer.h"
28
#include "callback_queue-inl.h"
29
#include "env.h"
30
#include "node.h"
31
#include "util-inl.h"
32
#include "uv.h"
33
#include "v8.h"
34
#include "node_perf_common.h"
35
#include "node_context_data.h"
36
37
#include <cstddef>
38
#include <cstdint>
39
40
#include <utility>
41
42
namespace node {
43
44
inline v8::Isolate* IsolateData::isolate() const {
45
  return isolate_;
46
}
47
48
917875
inline uv_loop_t* IsolateData::event_loop() const {
49
917875
  return event_loop_;
50
}
51
52
163351
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const {
53
163351
  return node_allocator_;
54
}
55
56
33829
inline MultiIsolatePlatform* IsolateData::platform() const {
57
33829
  return platform_;
58
}
59
60
430
inline void IsolateData::set_worker_context(worker::Worker* context) {
61
430
  CHECK_NULL(worker_context_);  // Should be set only once.
62
430
  worker_context_ = context;
63
430
}
64
65
12569
inline worker::Worker* IsolateData::worker_context() const {
66
12569
  return worker_context_;
67
}
68
69
219905
inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const {
70
439810
  return async_wrap_providers_[index].Get(isolate_);
71
}
72
73
3127244
inline AliasedUint32Array& AsyncHooks::fields() {
74
3127244
  return fields_;
75
}
76
77
1779996
inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
78
1779996
  return async_id_fields_;
79
}
80
81
469
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
82
469
  return async_ids_stack_;
83
}
84
85
873826
v8::Local<v8::Array> AsyncHooks::js_execution_async_resources() {
86
1747652
  if (UNLIKELY(js_execution_async_resources_.IsEmpty())) {
87
469
    js_execution_async_resources_.Reset(
88
938
        env()->isolate(), v8::Array::New(env()->isolate()));
89
  }
90
873826
  return PersistentToLocal::Strong(js_execution_async_resources_);
91
}
92
93
241
v8::Local<v8::Object> AsyncHooks::native_execution_async_resource(size_t i) {
94
241
  if (i >= native_execution_async_resources_.size()) return {};
95
241
  return PersistentToLocal::Strong(native_execution_async_resources_[i]);
96
}
97
98
239
inline void AsyncHooks::SetJSPromiseHooks(v8::Local<v8::Function> init,
99
                                          v8::Local<v8::Function> before,
100
                                          v8::Local<v8::Function> after,
101
                                          v8::Local<v8::Function> resolve) {
102
239
  js_promise_hooks_[0].Reset(env()->isolate(), init);
103
239
  js_promise_hooks_[1].Reset(env()->isolate(), before);
104
239
  js_promise_hooks_[2].Reset(env()->isolate(), after);
105
239
  js_promise_hooks_[3].Reset(env()->isolate(), resolve);
106
479
  for (auto it = contexts_.begin(); it != contexts_.end(); it++) {
107
480
    PersistentToLocal::Weak(env()->isolate(), *it)
108
240
        ->SetPromiseHooks(init, before, after, resolve);
109
  }
110
239
}
111
112
219441
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
113
219441
  return env()->isolate_data()->async_wrap_provider(idx);
114
}
115
116
1
inline void AsyncHooks::no_force_checks() {
117
1
  fields_[kCheck] -= 1;
118
1
}
119
120
1257233
inline Environment* AsyncHooks::env() {
121
1257233
  return Environment::ForAsyncHooks(this);
122
}
123
124
// Remember to keep this code aligned with pushAsyncContext() in JS.
125
826367
inline void AsyncHooks::push_async_context(double async_id,
126
                                           double trigger_async_id,
127
                                           v8::Local<v8::Object> resource) {
128
  // Since async_hooks is experimental, do only perform the check
129
  // when async_hooks is enabled.
130
826367
  if (fields_[kCheck] > 0) {
131
826379
    CHECK_GE(async_id, -1);
132
826379
    CHECK_GE(trigger_async_id, -1);
133
  }
134
135
826384
  uint32_t offset = fields_[kStackLength];
136
826322
  if (offset * 2 >= async_ids_stack_.Length())
137
10
    grow_async_ids_stack();
138
826309
  async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId];
139
826322
  async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId];
140
826357
  fields_[kStackLength] += 1;
141
826313
  async_id_fields_[kExecutionAsyncId] = async_id;
142
826318
  async_id_fields_[kTriggerAsyncId] = trigger_async_id;
143
144
#ifdef DEBUG
145
  for (uint32_t i = offset; i < native_execution_async_resources_.size(); i++)
146
    CHECK(native_execution_async_resources_[i].IsEmpty());
147
#endif
148
149
  // When this call comes from JS (as a way of increasing the stack size),
150
  // `resource` will be empty, because JS caches these values anyway, and
151
  // we should avoid creating strong global references that might keep
152
  // these JS resource objects alive longer than necessary.
153
826318
  if (!resource.IsEmpty()) {
154
826311
    native_execution_async_resources_.resize(offset + 1);
155
826232
    native_execution_async_resources_[offset].Reset(env()->isolate(), resource);
156
  }
157
826389
}
158
159
// Remember to keep this code aligned with popAsyncContext() in JS.
160
825862
inline bool AsyncHooks::pop_async_context(double async_id) {
161
  // In case of an exception then this may have already been reset, if the
162
  // stack was multiple MakeCallback()'s deep.
163
825862
  if (fields_[kStackLength] == 0) return false;
164
165
  // Ask for the async_id to be restored as a check that the stack
166
  // hasn't been corrupted.
167
  // Since async_hooks is experimental, do only perform the check
168
  // when async_hooks is enabled.
169

824827
  if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) {
170
4
    fprintf(stderr,
171
            "Error: async hook stack has become corrupted ("
172
            "actual: %.f, expected: %.f)\n",
173
            async_id_fields_.GetValue(kExecutionAsyncId),
174
4
            async_id);
175
4
    DumpBacktrace(stderr);
176
4
    fflush(stderr);
177
4
    if (!env()->abort_on_uncaught_exception())
178
4
      exit(1);
179
    fprintf(stderr, "\n");
180
    fflush(stderr);
181
    ABORT_NO_BACKTRACE();
182
  }
183
184
824771
  uint32_t offset = fields_[kStackLength] - 1;
185
824775
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
186
824872
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
187
824883
  fields_[kStackLength] = offset;
188
189

1649694
  if (LIKELY(offset < native_execution_async_resources_.size() &&
190
             !native_execution_async_resources_[offset].IsEmpty())) {
191
#ifdef DEBUG
192
    for (uint32_t i = offset + 1;
193
         i < native_execution_async_resources_.size();
194
         i++) {
195
      CHECK(native_execution_async_resources_[i].IsEmpty());
196
    }
197
#endif
198
824832
    native_execution_async_resources_.resize(offset);
199
1649676
    if (native_execution_async_resources_.size() <
200

1054323
            native_execution_async_resources_.capacity() / 2 &&
201
229483
        native_execution_async_resources_.size() > 16) {
202
      native_execution_async_resources_.shrink_to_fit();
203
    }
204
  }
205
206
1649632
  if (UNLIKELY(js_execution_async_resources()->Length() > offset)) {
207
97082
    v8::HandleScope handle_scope(env()->isolate());
208
145623
    USE(js_execution_async_resources()->Set(
209
        env()->context(),
210
        env()->length_string(),
211
242705
        v8::Integer::NewFromUnsigned(env()->isolate(), offset)));
212
  }
213
214
824817
  return fields_[kStackLength] > 0;
215
}
216
217
1783
void AsyncHooks::clear_async_id_stack() {
218
1783
  v8::Isolate* isolate = env()->isolate();
219
3566
  v8::HandleScope handle_scope(isolate);
220
3566
  if (!js_execution_async_resources_.IsEmpty()) {
221
3942
    USE(PersistentToLocal::Strong(js_execution_async_resources_)->Set(
222
        env()->context(),
223
        env()->length_string(),
224
6570
        v8::Integer::NewFromUnsigned(isolate, 0)));
225
  }
226
1783
  native_execution_async_resources_.clear();
227
1783
  native_execution_async_resources_.shrink_to_fit();
228
229
1783
  async_id_fields_[kExecutionAsyncId] = 0;
230
1783
  async_id_fields_[kTriggerAsyncId] = 0;
231
1783
  fields_[kStackLength] = 0;
232
1783
}
233
234
5826
inline void AsyncHooks::AddContext(v8::Local<v8::Context> ctx) {
235


52434
  ctx->SetPromiseHooks(
236
11652
    js_promise_hooks_[0].IsEmpty() ?
237
5826
      v8::Local<v8::Function>() :
238
      PersistentToLocal::Strong(js_promise_hooks_[0]),
239
11652
    js_promise_hooks_[1].IsEmpty() ?
240
5826
      v8::Local<v8::Function>() :
241
      PersistentToLocal::Strong(js_promise_hooks_[1]),
242
11652
    js_promise_hooks_[2].IsEmpty() ?
243
5826
      v8::Local<v8::Function>() :
244
      PersistentToLocal::Strong(js_promise_hooks_[2]),
245
11652
    js_promise_hooks_[3].IsEmpty() ?
246
5826
      v8::Local<v8::Function>() :
247
5826
      PersistentToLocal::Strong(js_promise_hooks_[3]));
248
249
5826
  size_t id = contexts_.size();
250
5826
  contexts_.resize(id + 1);
251
5826
  contexts_[id].Reset(env()->isolate(), ctx);
252
5826
  contexts_[id].SetWeak();
253
5826
}
254
255
493
inline void AsyncHooks::RemoveContext(v8::Local<v8::Context> ctx) {
256
493
  v8::Isolate* isolate = env()->isolate();
257
986
  v8::HandleScope handle_scope(isolate);
258
5271
  for (auto it = contexts_.begin(); it != contexts_.end(); it++) {
259
    v8::Local<v8::Context> saved_context =
260
4803
      PersistentToLocal::Weak(env()->isolate(), *it);
261
4803
    if (saved_context == ctx) {
262
25
      it->Reset();
263
25
      contexts_.erase(it);
264
25
      break;
265
    }
266
  }
267
493
}
268
269
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
270
// async_wrap-inl.h to avoid a circular dependency.
271
272
266983
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
273
266983
    Environment* env, double default_trigger_async_id)
274
266983
    : async_hooks_(env->async_hooks()) {
275
266983
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
276
266983
    CHECK_GE(default_trigger_async_id, 0);
277
  }
278
279
266983
  old_default_trigger_async_id_ =
280
533966
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
281
266983
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
282
266983
    default_trigger_async_id;
283
266983
}
284
285
533964
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
286
266982
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
287
533964
    old_default_trigger_async_id_;
288
266982
}
289
290
1257078
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
291
1257078
  return ContainerOf(&Environment::async_hooks_, hooks);
292
}
293
294
814507
inline size_t Environment::async_callback_scope_depth() const {
295
814507
  return async_callback_scope_depth_;
296
}
297
298
825487
inline void Environment::PushAsyncCallbackScope() {
299
825487
  async_callback_scope_depth_++;
300
825487
}
301
302
825025
inline void Environment::PopAsyncCallbackScope() {
303
825025
  async_callback_scope_depth_--;
304
825025
}
305
306
469
inline AliasedUint32Array& ImmediateInfo::fields() {
307
469
  return fields_;
308
}
309
310
210636
inline uint32_t ImmediateInfo::count() const {
311
210636
  return fields_[kCount];
312
}
313
314
321378
inline uint32_t ImmediateInfo::ref_count() const {
315
321378
  return fields_[kRefCount];
316
}
317
318
64286
inline bool ImmediateInfo::has_outstanding() const {
319
64286
  return fields_[kHasOutstanding] == 1;
320
}
321
322
33456
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
323
33456
  fields_[kRefCount] += increment;
324
33456
}
325
326
224573
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
327
224573
  fields_[kRefCount] -= decrement;
328
224576
}
329
330
469
inline AliasedUint8Array& TickInfo::fields() {
331
469
  return fields_;
332
}
333
334
1462249
inline bool TickInfo::has_tick_scheduled() const {
335
1462249
  return fields_[kHasTickScheduled] == 1;
336
}
337
338
559873
inline bool TickInfo::has_rejection_to_warn() const {
339
559873
  return fields_[kHasRejectionToWarn] == 1;
340
}
341
342
5826
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
343
                                         const ContextInfo& info) {
344
5826
  context->SetAlignedPointerInEmbedderData(
345
5826
      ContextEmbedderIndex::kEnvironment, this);
346
  // Used by Environment::GetCurrent to know that we are on a node context.
347
11652
  context->SetAlignedPointerInEmbedderData(
348
5826
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
349
  // Used to retrieve bindings
350
5826
  context->SetAlignedPointerInEmbedderData(
351
11652
      ContextEmbedderIndex::kBindingListIndex, &(this->bindings_));
352
353
#if HAVE_INSPECTOR
354
5826
  inspector_agent()->ContextCreated(context, info);
355
#endif  // HAVE_INSPECTOR
356
357
5826
  this->async_hooks()->AddContext(context);
358
5826
}
359
360
970705
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
361
970705
  if (UNLIKELY(!isolate->InContext())) return nullptr;
362
1937464
  v8::HandleScope handle_scope(isolate);
363
968716
  return GetCurrent(isolate->GetCurrentContext());
364
}
365
366
6028068
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
367
6028068
  if (UNLIKELY(context.IsEmpty())) {
368
1
    return nullptr;
369
  }
370
6028067
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
371
               ContextEmbedderIndex::kContextTag)) {
372
11
    return nullptr;
373
  }
374
12056636
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
375
                   ContextEmbedderIndex::kContextTag) !=
376
               Environment::kNodeContextTagPtr)) {
377
    return nullptr;
378
  }
379
  return static_cast<Environment*>(
380
6028318
      context->GetAlignedPointerFromEmbedderData(
381
6028318
          ContextEmbedderIndex::kEnvironment));
382
}
383
384
3323592
inline Environment* Environment::GetCurrent(
385
    const v8::FunctionCallbackInfo<v8::Value>& info) {
386
3323592
  return GetCurrent(info.GetIsolate()->GetCurrentContext());
387
}
388
389
template <typename T>
390
1260084
inline Environment* Environment::GetCurrent(
391
    const v8::PropertyCallbackInfo<T>& info) {
392
1260084
  return GetCurrent(info.GetIsolate()->GetCurrentContext());
393
}
394
395
template <typename T, typename U>
396
inline T* Environment::GetBindingData(const v8::PropertyCallbackInfo<U>& info) {
397
  return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
398
}
399
400
template <typename T>
401
713216
inline T* Environment::GetBindingData(
402
    const v8::FunctionCallbackInfo<v8::Value>& info) {
403
713216
  return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
404
}
405
406
template <typename T>
407
713219
inline T* Environment::GetBindingData(v8::Local<v8::Context> context) {
408
  BindingDataStore* map = static_cast<BindingDataStore*>(
409
713219
      context->GetAlignedPointerFromEmbedderData(
410
713219
          ContextEmbedderIndex::kBindingListIndex));
411
  DCHECK_NOT_NULL(map);
412
713219
  auto it = map->find(T::type_name);
413
713215
  if (UNLIKELY(it == map->end())) return nullptr;
414
713211
  T* result = static_cast<T*>(it->second.get());
415
  DCHECK_NOT_NULL(result);
416
  DCHECK_EQ(result->env(), GetCurrent(context));
417
713209
  return result;
418
}
419
420
template <typename T>
421
11518
inline T* Environment::AddBindingData(
422
    v8::Local<v8::Context> context,
423
    v8::Local<v8::Object> target) {
424
  DCHECK_EQ(GetCurrent(context), this);
425
  // This won't compile if T is not a BaseObject subclass.
426
23036
  BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target);
427
  BindingDataStore* map = static_cast<BindingDataStore*>(
428
11518
      context->GetAlignedPointerFromEmbedderData(
429
11518
          ContextEmbedderIndex::kBindingListIndex));
430
  DCHECK_NOT_NULL(map);
431
11518
  auto result = map->emplace(T::type_name, item);
432
11518
  CHECK(result.second);
433
  DCHECK_EQ(GetBindingData<T>(context), item.get());
434
23036
  return item.get();
435
}
436
437
24757580
inline v8::Isolate* Environment::isolate() const {
438
24757580
  return isolate_;
439
}
440
441
5778
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
442
5778
  return ContainerOf(&Environment::timer_handle_, handle);
443
}
444
445
24318
inline uv_timer_t* Environment::timer_handle() {
446
24318
  return &timer_handle_;
447
}
448
449
210637
inline Environment* Environment::from_immediate_check_handle(
450
    uv_check_t* handle) {
451
210637
  return ContainerOf(&Environment::immediate_check_handle_, handle);
452
}
453
454
20824
inline uv_check_t* Environment::immediate_check_handle() {
455
20824
  return &immediate_check_handle_;
456
}
457
458
253188
inline uv_idle_t* Environment::immediate_idle_handle() {
459
253188
  return &immediate_idle_handle_;
460
}
461
462
31236
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
463
                                               HandleCleanupCb cb,
464
                                               void* arg) {
465
31236
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
466
31236
}
467
468
template <typename T, typename OnCloseCallback>
469
32118
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
470
32118
  handle_cleanup_waiting_++;
471
  static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
472
  static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
473
                "T is a libuv handle");
474
  static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
475
                "T is a libuv handle");
476
  struct CloseData {
477
    Environment* env;
478
    OnCloseCallback callback;
479
    void* original_data;
480
  };
481
32118
  handle->data = new CloseData { this, callback, handle->data };
482
128481
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
483
64230
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
484
32117
    data->env->handle_cleanup_waiting_--;
485
32110
    handle->data = data->original_data;
486
32110
    data->callback(reinterpret_cast<T*>(handle));
487
32117
  });
488
32122
}
489
490
83760
void Environment::IncreaseWaitingRequestCounter() {
491
83760
  request_waiting_++;
492
83760
}
493
494
83749
void Environment::DecreaseWaitingRequestCounter() {
495
83749
  request_waiting_--;
496
83749
  CHECK_GE(request_waiting_, 0);
497
83749
}
498
499
912636
inline uv_loop_t* Environment::event_loop() const {
500
912636
  return isolate_data()->event_loop();
501
}
502
503
163
inline void Environment::TryLoadAddon(
504
    const char* filename,
505
    int flags,
506
    const std::function<bool(binding::DLib*)>& was_loaded) {
507
163
  loaded_addons_.emplace_back(filename, flags);
508
163
  if (!was_loaded(&loaded_addons_.back())) {
509
8
    loaded_addons_.pop_back();
510
  }
511
163
}
512
513
#if HAVE_INSPECTOR
514
22917
inline bool Environment::is_in_inspector_console_call() const {
515
22917
  return is_in_inspector_console_call_;
516
}
517
518
45832
inline void Environment::set_is_in_inspector_console_call(bool value) {
519
45832
  is_in_inspector_console_call_ = value;
520
45832
}
521
#endif
522
523
5425721
inline AsyncHooks* Environment::async_hooks() {
524
5425721
  return &async_hooks_;
525
}
526
527
854795
inline ImmediateInfo* Environment::immediate_info() {
528
854795
  return &immediate_info_;
529
}
530
531
731578
inline TickInfo* Environment::tick_info() {
532
731578
  return &tick_info_;
533
}
534
535
55040
inline uint64_t Environment::timer_base() const {
536
55040
  return timer_base_;
537
}
538
539
1273791
inline std::shared_ptr<KVStore> Environment::env_vars() {
540
1273791
  return env_vars_;
541
}
542
543
5654
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
544
5654
  env_vars_ = env_vars;
545
5654
}
546
547
17
inline bool Environment::printed_error() const {
548
17
  return printed_error_;
549
}
550
551
17
inline void Environment::set_printed_error(bool value) {
552
17
  printed_error_ = value;
553
17
}
554
555
9426
inline void Environment::set_trace_sync_io(bool value) {
556
9426
  trace_sync_io_ = value;
557
9426
}
558
559
83
inline bool Environment::abort_on_uncaught_exception() const {
560
83
  return options_->abort_on_uncaught_exception;
561
}
562
563
inline void Environment::set_force_context_aware(bool value) {
564
  options_->force_context_aware = value;
565
}
566
567
42
inline bool Environment::force_context_aware() const {
568
42
  return options_->force_context_aware;
569
}
570
571
418
inline void Environment::set_abort_on_uncaught_exception(bool value) {
572
418
  options_->abort_on_uncaught_exception = value;
573
418
}
574
575
499
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
576
499
  return should_abort_on_uncaught_toggle_;
577
}
578
579
305487
inline AliasedInt32Array& Environment::stream_base_state() {
580
305487
  return stream_base_state_;
581
}
582
583
42827
inline uint32_t Environment::get_next_module_id() {
584
42827
  return module_id_counter_++;
585
}
586
2192
inline uint32_t Environment::get_next_script_id() {
587
2192
  return script_id_counter_++;
588
}
589
32148
inline uint32_t Environment::get_next_function_id() {
590
32148
  return function_id_counter_++;
591
}
592
593
87587
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
594
87587
    Environment* env)
595
87587
    : env_(env) {
596
87587
  env_->PushShouldNotAbortOnUncaughtScope();
597
87587
}
598
599
175172
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
600
87586
  Close();
601
87586
}
602
603
87768
void ShouldNotAbortOnUncaughtScope::Close() {
604
87768
  if (env_ != nullptr) {
605
87586
    env_->PopShouldNotAbortOnUncaughtScope();
606
87586
    env_ = nullptr;
607
  }
608
87768
}
609
610
87587
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
611
87587
  should_not_abort_scope_counter_++;
612
87587
}
613
614
87586
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
615
87586
  should_not_abort_scope_counter_--;
616
87586
}
617
618
1
inline bool Environment::inside_should_not_abort_on_uncaught_scope() const {
619
1
  return should_not_abort_scope_counter_ > 0;
620
}
621
622
387914
inline std::vector<double>* Environment::destroy_async_id_list() {
623
387914
  return &destroy_async_id_list_;
624
}
625
626
220125
inline double Environment::new_async_id() {
627
220125
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
628
220125
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
629
}
630
631
252123
inline double Environment::execution_async_id() {
632
252123
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
633
}
634
635
66091
inline double Environment::trigger_async_id() {
636
66091
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
637
}
638
639
220122
inline double Environment::get_default_trigger_async_id() {
640
  double default_trigger_async_id =
641
220122
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
642
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
643
220122
  if (default_trigger_async_id < 0)
644
174637
    default_trigger_async_id = execution_async_id();
645
220122
  return default_trigger_async_id;
646
}
647
648
59089
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
649
59089
  return options_;
650
}
651
652
15082
inline const std::vector<std::string>& Environment::argv() {
653
15082
  return argv_;
654
}
655
656
5751
inline const std::vector<std::string>& Environment::exec_argv() {
657
5751
  return exec_argv_;
658
}
659
660
10412
inline const std::string& Environment::exec_path() const {
661
10412
  return exec_path_;
662
}
663
664
11
inline std::string Environment::GetCwd() {
665
  char cwd[PATH_MAX_BYTES];
666
11
  size_t size = PATH_MAX_BYTES;
667
11
  const int err = uv_cwd(cwd, &size);
668
669
11
  if (err == 0) {
670
11
    CHECK_GT(size, 0);
671
11
    return cwd;
672
  }
673
674
  // This can fail if the cwd is deleted. In that case, fall back to
675
  // exec_path.
676
  const std::string& exec_path = exec_path_;
677
  return exec_path.substr(0, exec_path.find_last_of(kPathSeparator));
678
}
679
680
#if HAVE_INSPECTOR
681
5200
inline void Environment::set_coverage_directory(const char* dir) {
682
5200
  coverage_directory_ = std::string(dir);
683
5200
}
684
685
5221
inline void Environment::set_coverage_connection(
686
    std::unique_ptr<profiler::V8CoverageConnection> connection) {
687
5221
  CHECK_NULL(coverage_connection_);
688
5221
  std::swap(coverage_connection_, connection);
689
5221
}
690
691
15663
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
692
15663
  return coverage_connection_.get();
693
}
694
695
5185
inline const std::string& Environment::coverage_directory() const {
696
5185
  return coverage_directory_;
697
}
698
699
12
inline void Environment::set_cpu_profiler_connection(
700
    std::unique_ptr<profiler::V8CpuProfilerConnection> connection) {
701
12
  CHECK_NULL(cpu_profiler_connection_);
702
12
  std::swap(cpu_profiler_connection_, connection);
703
12
}
704
705
inline profiler::V8CpuProfilerConnection*
706
5238
Environment::cpu_profiler_connection() {
707
5238
  return cpu_profiler_connection_.get();
708
}
709
710
12
inline void Environment::set_cpu_prof_interval(uint64_t interval) {
711
12
  cpu_prof_interval_ = interval;
712
12
}
713
714
12
inline uint64_t Environment::cpu_prof_interval() const {
715
12
  return cpu_prof_interval_;
716
}
717
718
12
inline void Environment::set_cpu_prof_name(const std::string& name) {
719
12
  cpu_prof_name_ = name;
720
12
}
721
722
12
inline const std::string& Environment::cpu_prof_name() const {
723
12
  return cpu_prof_name_;
724
}
725
726
12
inline void Environment::set_cpu_prof_dir(const std::string& dir) {
727
12
  cpu_prof_dir_ = dir;
728
12
}
729
730
12
inline const std::string& Environment::cpu_prof_dir() const {
731
12
  return cpu_prof_dir_;
732
}
733
734
12
inline void Environment::set_heap_profiler_connection(
735
    std::unique_ptr<profiler::V8HeapProfilerConnection> connection) {
736
12
  CHECK_NULL(heap_profiler_connection_);
737
12
  std::swap(heap_profiler_connection_, connection);
738
12
}
739
740
inline profiler::V8HeapProfilerConnection*
741
5226
Environment::heap_profiler_connection() {
742
5226
  return heap_profiler_connection_.get();
743
}
744
745
12
inline void Environment::set_heap_prof_name(const std::string& name) {
746
12
  heap_prof_name_ = name;
747
12
}
748
749
12
inline const std::string& Environment::heap_prof_name() const {
750
12
  return heap_prof_name_;
751
}
752
753
12
inline void Environment::set_heap_prof_dir(const std::string& dir) {
754
12
  heap_prof_dir_ = dir;
755
12
}
756
757
12
inline const std::string& Environment::heap_prof_dir() const {
758
12
  return heap_prof_dir_;
759
}
760
761
12
inline void Environment::set_heap_prof_interval(uint64_t interval) {
762
12
  heap_prof_interval_ = interval;
763
12
}
764
765
12
inline uint64_t Environment::heap_prof_interval() const {
766
12
  return heap_prof_interval_;
767
}
768
769
#endif  // HAVE_INSPECTOR
770
771
inline
772
10612
std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() {
773
10612
  return inspector_host_port_;
774
}
775
776
87314
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
777
87314
  return options_;
778
}
779
780
112
inline void IsolateData::set_options(
781
    std::shared_ptr<PerIsolateOptions> options) {
782
112
  options_ = std::move(options);
783
112
}
784
785
template <typename Fn>
786
56506
void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) {
787
113012
  auto callback = native_immediates_.CreateCallback(std::move(cb), flags);
788
56506
  native_immediates_.Push(std::move(callback));
789
790






56506
  if (flags & CallbackFlags::kRefed) {
791






33456
    if (immediate_info()->ref_count() == 0)
792
25127
      ToggleImmediateRef(true);
793
33456
    immediate_info()->ref_count_inc(1);
794
  }
795
56506
}
796
797
template <typename Fn>
798
1195
void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) {
799
  auto callback = native_immediates_threadsafe_.CreateCallback(
800
2390
      std::move(cb), flags);
801
  {
802
2390
    Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
803
1195
    native_immediates_threadsafe_.Push(std::move(callback));
804

1195
    if (task_queues_async_initialized_)
805
979
      uv_async_send(&task_queues_async_);
806
  }
807
1195
}
808
809
template <typename Fn>
810
8707
void Environment::RequestInterrupt(Fn&& cb) {
811
  auto callback = native_immediates_interrupts_.CreateCallback(
812
17414
      std::move(cb), CallbackFlags::kRefed);
813
  {
814
17414
    Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
815
8707
    native_immediates_interrupts_.Push(std::move(callback));
816
8707
    if (task_queues_async_initialized_)
817
3358
      uv_async_send(&task_queues_async_);
818
  }
819
8707
  RequestInterruptFromV8();
820
8707
}
821
822
3005303
inline bool Environment::can_call_into_js() const {
823

3005303
  return can_call_into_js_ && !is_stopping();
824
}
825
826
1101
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
827
1101
  can_call_into_js_ = can_call_into_js;
828
1101
}
829
830
1402870
inline bool Environment::has_run_bootstrapping_code() const {
831
1402870
  return has_run_bootstrapping_code_;
832
}
833
834
5239
inline void Environment::DoneBootstrapping() {
835
5239
  has_run_bootstrapping_code_ = true;
836
  // This adjusts the return value of base_object_created_after_bootstrap() so
837
  // that tests that check the count do not have to account for internally
838
  // created BaseObjects.
839
5239
  base_object_created_by_bootstrap_ = base_object_count_;
840
5239
}
841
842
19
inline bool Environment::has_serialized_options() const {
843
19
  return has_serialized_options_;
844
}
845
846
5206
inline void Environment::set_has_serialized_options(bool value) {
847
5206
  has_serialized_options_ = value;
848
5206
}
849
850
6964
inline bool Environment::is_main_thread() const {
851
6964
  return worker_context() == nullptr;
852
}
853
854
5206
inline bool Environment::should_not_register_esm_loader() const {
855
5206
  return flags_ & EnvironmentFlags::kNoRegisterESMLoader;
856
}
857
858
12874
inline bool Environment::owns_process_state() const {
859
12874
  return flags_ & EnvironmentFlags::kOwnsProcessState;
860
}
861
862
5231
inline bool Environment::owns_inspector() const {
863
5231
  return flags_ & EnvironmentFlags::kOwnsInspector;
864
}
865
866
111650
inline bool Environment::tracks_unmanaged_fds() const {
867
111650
  return flags_ & EnvironmentFlags::kTrackUnmanagedFds;
868
}
869
870
2
bool Environment::filehandle_close_warning() const {
871
2
  return emit_filehandle_warning_;
872
}
873
874
2
void Environment::set_filehandle_close_warning(bool on) {
875
2
  emit_filehandle_warning_ = on;
876
2
}
877
878
16
void Environment::set_source_maps_enabled(bool on) {
879
16
  source_maps_enabled_ = on;
880
16
}
881
882
935
bool Environment::source_maps_enabled() const {
883
935
  return source_maps_enabled_;
884
}
885
886
6151
inline uint64_t Environment::thread_id() const {
887
6151
  return thread_id_;
888
}
889
890
12569
inline worker::Worker* Environment::worker_context() const {
891
12569
  return isolate_data()->worker_context();
892
}
893
894
652
inline void Environment::add_sub_worker_context(worker::Worker* context) {
895
652
  sub_worker_contexts_.insert(context);
896
652
}
897
898
679
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
899
679
  sub_worker_contexts_.erase(context);
900
679
}
901
902
template <typename Fn>
903
24
inline void Environment::ForEachWorker(Fn&& iterator) {
904
24
  for (worker::Worker* w : sub_worker_contexts_) iterator(w);
905
24
}
906
907
1288
inline void Environment::add_refs(int64_t diff) {
908
1288
  task_queues_async_refs_ += diff;
909
1288
  CHECK_GE(task_queues_async_refs_, 0);
910
1288
  if (task_queues_async_refs_ == 0)
911
169
    uv_unref(reinterpret_cast<uv_handle_t*>(&task_queues_async_));
912
  else
913
1119
    uv_ref(reinterpret_cast<uv_handle_t*>(&task_queues_async_));
914
1288
}
915
916
4569070
inline bool Environment::is_stopping() const {
917
4569070
  return is_stopping_.load();
918
}
919
920
4786
inline void Environment::set_stopping(bool value) {
921
4786
  is_stopping_.store(value);
922
4786
}
923
924
3
inline std::list<node_module>* Environment::extra_linked_bindings() {
925
3
  return &extra_linked_bindings_;
926
}
927
928
7
inline node_module* Environment::extra_linked_bindings_head() {
929
10
  return extra_linked_bindings_.size() > 0 ?
930
10
      &extra_linked_bindings_.front() : nullptr;
931
}
932
933
7
inline const Mutex& Environment::extra_linked_bindings_mutex() const {
934
7
  return extra_linked_bindings_mutex_;
935
}
936
937
43546
inline performance::PerformanceState* Environment::performance_state() {
938
43546
  return performance_state_.get();
939
}
940
941
5464471
inline IsolateData* Environment::isolate_data() const {
942
5464471
  return isolate_data_;
943
}
944
945
std::unordered_map<char*, std::unique_ptr<v8::BackingStore>>*
946
134250
    Environment::released_allocated_buffers() {
947
134250
  return &released_allocated_buffers_;
948
}
949
950
8
inline void Environment::ThrowError(const char* errmsg) {
951
8
  ThrowError(v8::Exception::Error, errmsg);
952
8
}
953
954
inline void Environment::ThrowTypeError(const char* errmsg) {
955
  ThrowError(v8::Exception::TypeError, errmsg);
956
}
957
958
inline void Environment::ThrowRangeError(const char* errmsg) {
959
  ThrowError(v8::Exception::RangeError, errmsg);
960
}
961
962
8
inline void Environment::ThrowError(
963
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
964
    const char* errmsg) {
965
16
  v8::HandleScope handle_scope(isolate());
966
8
  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
967
8
}
968
969
7
inline void Environment::ThrowErrnoException(int errorno,
970
                                             const char* syscall,
971
                                             const char* message,
972
                                             const char* path) {
973
  isolate()->ThrowException(
974
7
      ErrnoException(isolate(), errorno, syscall, message, path));
975
7
}
976
977
14
inline void Environment::ThrowUVException(int errorno,
978
                                          const char* syscall,
979
                                          const char* message,
980
                                          const char* path,
981
                                          const char* dest) {
982
  isolate()->ThrowException(
983
14
      UVException(isolate(), errorno, syscall, message, path, dest));
984
14
}
985
986
inline v8::Local<v8::FunctionTemplate>
987
1494104
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
988
                                     v8::Local<v8::Signature> signature,
989
                                     v8::ConstructorBehavior behavior,
990
                                     v8::SideEffectType side_effect_type) {
991
  return v8::FunctionTemplate::New(isolate(), callback, v8::Local<v8::Value>(),
992
1494104
                                   signature, 0, behavior, side_effect_type);
993
}
994
995
247908
inline void Environment::SetMethod(v8::Local<v8::Object> that,
996
                                   const char* name,
997
                                   v8::FunctionCallback callback) {
998
247908
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
999
  v8::Local<v8::Function> function =
1000
495814
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1001
                          v8::ConstructorBehavior::kThrow,
1002
247908
                          v8::SideEffectType::kHasSideEffect)
1003
495812
          ->GetFunction(context)
1004
247908
          .ToLocalChecked();
1005
  // kInternalized strings are created in the old space.
1006
247908
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1007
  v8::Local<v8::String> name_string =
1008
495817
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1009
495818
  that->Set(context, name_string, function).Check();
1010
247909
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1011
247917
}
1012
1013
104132
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
1014
                                               const char* name,
1015
                                               v8::FunctionCallback callback) {
1016
104132
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1017
  v8::Local<v8::Function> function =
1018
208261
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1019
                          v8::ConstructorBehavior::kThrow,
1020
104133
                          v8::SideEffectType::kHasNoSideEffect)
1021
208258
          ->GetFunction(context)
1022
104133
          .ToLocalChecked();
1023
  // kInternalized strings are created in the old space.
1024
104133
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1025
  v8::Local<v8::String> name_string =
1026
208268
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1027
208268
  that->Set(context, name_string, function).Check();
1028
104133
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1029
104134
}
1030
1031
724931
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1032
                                        const char* name,
1033
                                        v8::FunctionCallback callback) {
1034
724931
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1035
  v8::Local<v8::FunctionTemplate> t =
1036
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1037
724929
                          v8::SideEffectType::kHasSideEffect);
1038
  // kInternalized strings are created in the old space.
1039
724925
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1040
  v8::Local<v8::String> name_string =
1041
1449853
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1042
1449858
  that->PrototypeTemplate()->Set(name_string, t);
1043
724930
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1044
724937
}
1045
1046
170235
inline void Environment::SetProtoMethodNoSideEffect(
1047
    v8::Local<v8::FunctionTemplate> that,
1048
    const char* name,
1049
    v8::FunctionCallback callback) {
1050
170235
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1051
  v8::Local<v8::FunctionTemplate> t =
1052
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1053
170235
                          v8::SideEffectType::kHasNoSideEffect);
1054
  // kInternalized strings are created in the old space.
1055
170234
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1056
  v8::Local<v8::String> name_string =
1057
340469
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1058
340470
  that->PrototypeTemplate()->Set(name_string, t);
1059
170235
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1060
170235
}
1061
1062
32
inline void Environment::SetInstanceMethod(v8::Local<v8::FunctionTemplate> that,
1063
                                           const char* name,
1064
                                           v8::FunctionCallback callback) {
1065
32
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1066
  v8::Local<v8::FunctionTemplate> t =
1067
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1068
32
                          v8::SideEffectType::kHasSideEffect);
1069
  // kInternalized strings are created in the old space.
1070
32
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1071
  v8::Local<v8::String> name_string =
1072
64
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1073
64
  that->InstanceTemplate()->Set(name_string, t);
1074
32
  t->SetClassName(name_string);
1075
32
}
1076
1077
186475
inline void Environment::SetConstructorFunction(
1078
    v8::Local<v8::Object> that,
1079
    const char* name,
1080
    v8::Local<v8::FunctionTemplate> tmpl,
1081
    SetConstructorFunctionFlag flag) {
1082
186475
  SetConstructorFunction(that, OneByteString(isolate(), name), tmpl, flag);
1083
186476
}
1084
1085
196220
inline void Environment::SetConstructorFunction(
1086
    v8::Local<v8::Object> that,
1087
    v8::Local<v8::String> name,
1088
    v8::Local<v8::FunctionTemplate> tmpl,
1089
    SetConstructorFunctionFlag flag) {
1090
196220
  if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME))
1091
191129
    tmpl->SetClassName(name);
1092
392440
  that->Set(
1093
      context(),
1094
      name,
1095
981100
      tmpl->GetFunction(context()).ToLocalChecked()).Check();
1096
196220
}
1097
1098
340167
void Environment::AddCleanupHook(CleanupCallback fn, void* arg) {
1099
680331
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1100
340167
    fn, arg, cleanup_hook_counter_++
1101
340167
  });
1102
  // Make sure there was no existing element with these values.
1103
340164
  CHECK_EQ(insertion_info.second, true);
1104
340164
}
1105
1106
324858
void Environment::RemoveCleanupHook(CleanupCallback fn, void* arg) {
1107
324858
  CleanupHookCallback search { fn, arg, 0 };
1108
324858
  cleanup_hooks_.erase(search);
1109
324870
}
1110
1111
869378
size_t CleanupHookCallback::Hash::operator()(
1112
    const CleanupHookCallback& cb) const {
1113
869378
  return std::hash<void*>()(cb.arg_);
1114
}
1115
1116
431029
bool CleanupHookCallback::Equal::operator()(
1117
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1118

431029
  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
1119
}
1120
1121
451
BaseObject* CleanupHookCallback::GetBaseObject() const {
1122
451
  if (fn_ == BaseObject::DeleteMe)
1123
429
    return static_cast<BaseObject*>(arg_);
1124
  else
1125
22
    return nullptr;
1126
}
1127
1128
template <typename T>
1129
22
void Environment::ForEachBaseObject(T&& iterator) {
1130

473
  for (const auto& hook : cleanup_hooks_) {
1131
451
    BaseObject* obj = hook.GetBaseObject();
1132

451
    if (obj != nullptr)
1133
429
      iterator(obj);
1134
  }
1135
22
}
1136
1137
template <typename T>
1138
8
void Environment::ForEachBindingData(T&& iterator) {
1139
  BindingDataStore* map = static_cast<BindingDataStore*>(
1140
24
      context()->GetAlignedPointerFromEmbedderData(
1141
8
          ContextEmbedderIndex::kBindingListIndex));
1142
  DCHECK_NOT_NULL(map);
1143
24
  for (auto& it : *map) {
1144
16
    iterator(it.first, it.second);
1145
  }
1146
8
}
1147
1148
653141
void Environment::modify_base_object_count(int64_t delta) {
1149
653141
  base_object_count_ += delta;
1150
653141
}
1151
1152
14
int64_t Environment::base_object_created_after_bootstrap() const {
1153
14
  return base_object_count_ - base_object_created_by_bootstrap_;
1154
}
1155
1156
2
int64_t Environment::base_object_count() const {
1157
2
  return base_object_count_;
1158
}
1159
1160
15
void Environment::set_main_utf16(std::unique_ptr<v8::String::Value> str) {
1161
15
  CHECK(!main_utf16_);
1162
15
  main_utf16_ = std::move(str);
1163
15
}
1164
1165
418
void Environment::set_process_exit_handler(
1166
    std::function<void(Environment*, int)>&& handler) {
1167
418
  process_exit_handler_ = std::move(handler);
1168
418
}
1169
1170
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1171
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1172
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1173
#define V(TypeName, PropertyName)                                             \
1174
  inline                                                                      \
1175
  v8::Local<TypeName> IsolateData::PropertyName() const {                     \
1176
    return PropertyName ## _ .Get(isolate_);                                  \
1177
  }
1178
217
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1179
76414
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1180
7130025
  PER_ISOLATE_STRING_PROPERTIES(VS)
1181
263389
#undef V
1182
16977
#undef VS
1183
8821
#undef VY
1184
4733
#undef VP
1185
30137
1186
116726
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1187
17417
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1188
22867
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1189
84766
#define V(TypeName, PropertyName)                                             \
1190
87844
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1191
101
    return isolate_data()->PropertyName();                                    \
1192
118
  }
1193
32414
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1194
103037
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1195
3649643
  PER_ISOLATE_STRING_PROPERTIES(VS)
1196
123721
#undef V
1197
2534
#undef VS
1198
12989
#undef VY
1199
3128
#undef VP
1200
43470
1201
92118
#define V(PropertyName, TypeName)                                             \
1202
8500
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1203
15027
    return PersistentToLocal::Strong(PropertyName ## _);                      \
1204
51524
  }                                                                           \
1205
37550
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
1206
68
    PropertyName ## _.Reset(isolate(), value);                                \
1207
68
  }
1208
425881
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1209
1762325
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1210
197621
#undef V
1211
187947
1212
6787441
v8::Local<v8::Context> Environment::context() const {
1213
7134134
  return PersistentToLocal::Strong(context_);
1214
527875
}
1215
89906
1216
74229
}  // namespace node
1217
15810
1218
28348
// These two files depend on each other. Including base_object-inl.h after this
1219
28729
// file is the easiest way to avoid issues with that circular dependency.
1220
51888
#include "base_object-inl.h"
1221
46641
1222
66989
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1223
65598
1224
16186
#endif  // SRC_ENV_INL_H_