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-04 04:12:13 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
902225
inline uv_loop_t* IsolateData::event_loop() const {
49
902225
  return event_loop_;
50
}
51
52
163802
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const {
53
163802
  return node_allocator_;
54
}
55
56
33903
inline MultiIsolatePlatform* IsolateData::platform() const {
57
33903
  return platform_;
58
}
59
60
431
inline void IsolateData::set_worker_context(worker::Worker* context) {
61
431
  CHECK_NULL(worker_context_);  // Should be set only once.
62
431
  worker_context_ = context;
63
431
}
64
65
12665
inline worker::Worker* IsolateData::worker_context() const {
66
12665
  return worker_context_;
67
}
68
69
219651
inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const {
70
439302
  return async_wrap_providers_[index].Get(isolate_);
71
}
72
73
3118411
inline AliasedUint32Array& AsyncHooks::fields() {
74
3118411
  return fields_;
75
}
76
77
1778249
inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
78
1778249
  return async_id_fields_;
79
}
80
81
470
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
82
470
  return async_ids_stack_;
83
}
84
85
865270
v8::Local<v8::Array> AsyncHooks::js_execution_async_resources() {
86
1730540
  if (UNLIKELY(js_execution_async_resources_.IsEmpty())) {
87
470
    js_execution_async_resources_.Reset(
88
940
        env()->isolate(), v8::Array::New(env()->isolate()));
89
  }
90
865270
  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
219187
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
113
219187
  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
1245717
inline Environment* AsyncHooks::env() {
121
1245717
  return Environment::ForAsyncHooks(this);
122
}
123
124
// Remember to keep this code aligned with pushAsyncContext() in JS.
125
818383
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
818383
  if (fields_[kCheck] > 0) {
131
818548
    CHECK_GE(async_id, -1);
132
818548
    CHECK_GE(trigger_async_id, -1);
133
  }
134
135
818639
  uint32_t offset = fields_[kStackLength];
136
818633
  if (offset * 2 >= async_ids_stack_.Length())
137
10
    grow_async_ids_stack();
138
818656
  async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId];
139
818605
  async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId];
140
818637
  fields_[kStackLength] += 1;
141
818640
  async_id_fields_[kExecutionAsyncId] = async_id;
142
818629
  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
818623
  if (!resource.IsEmpty()) {
154
818628
    native_execution_async_resources_.resize(offset + 1);
155
818525
    native_execution_async_resources_[offset].Reset(env()->isolate(), resource);
156
  }
157
818650
}
158
159
// Remember to keep this code aligned with popAsyncContext() in JS.
160
818201
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
818201
  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

817171
  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
817142
  uint32_t offset = fields_[kStackLength] - 1;
185
817143
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
186
817182
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
187
817193
  fields_[kStackLength] = offset;
188
189

1634331
  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
817157
    native_execution_async_resources_.resize(offset);
199
1634290
    if (native_execution_async_resources_.size() <
200

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


52362
  ctx->SetPromiseHooks(
236
11636
    js_promise_hooks_[0].IsEmpty() ?
237
5819
      v8::Local<v8::Function>() :
238
      PersistentToLocal::Strong(js_promise_hooks_[0]),
239
11636
    js_promise_hooks_[1].IsEmpty() ?
240
5819
      v8::Local<v8::Function>() :
241
      PersistentToLocal::Strong(js_promise_hooks_[1]),
242
11636
    js_promise_hooks_[2].IsEmpty() ?
243
5819
      v8::Local<v8::Function>() :
244
      PersistentToLocal::Strong(js_promise_hooks_[2]),
245
11636
    js_promise_hooks_[3].IsEmpty() ?
246
5819
      v8::Local<v8::Function>() :
247
5818
      PersistentToLocal::Strong(js_promise_hooks_[3]));
248
249
5819
  size_t id = contexts_.size();
250
5818
  contexts_.resize(id + 1);
251
5819
  contexts_[id].Reset(env()->isolate(), ctx);
252
5819
  contexts_[id].SetWeak();
253
5819
}
254
255
485
inline void AsyncHooks::RemoveContext(v8::Local<v8::Context> ctx) {
256
485
  v8::Isolate* isolate = env()->isolate();
257
970
  v8::HandleScope handle_scope(isolate);
258
5031
  for (auto it = contexts_.begin(); it != contexts_.end(); it++) {
259
    v8::Local<v8::Context> saved_context =
260
4571
      PersistentToLocal::Weak(env()->isolate(), *it);
261
4571
    if (saved_context == ctx) {
262
25
      it->Reset();
263
25
      contexts_.erase(it);
264
25
      break;
265
    }
266
  }
267
485
}
268
269
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
270
// async_wrap-inl.h to avoid a circular dependency.
271
272
266771
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
273
266771
    Environment* env, double default_trigger_async_id)
274
266771
    : async_hooks_(env->async_hooks()) {
275
266771
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
276
266771
    CHECK_GE(default_trigger_async_id, 0);
277
  }
278
279
266771
  old_default_trigger_async_id_ =
280
533542
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
281
266771
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
282
266771
    default_trigger_async_id;
283
266771
}
284
285
533540
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
286
266770
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
287
533540
    old_default_trigger_async_id_;
288
266770
}
289
290
1245567
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
291
1245567
  return ContainerOf(&Environment::async_hooks_, hooks);
292
}
293
294
806814
inline size_t Environment::async_callback_scope_depth() const {
295
806814
  return async_callback_scope_depth_;
296
}
297
298
817860
inline void Environment::PushAsyncCallbackScope() {
299
817860
  async_callback_scope_depth_++;
300
817860
}
301
302
817562
inline void Environment::PopAsyncCallbackScope() {
303
817562
  async_callback_scope_depth_--;
304
817562
}
305
306
470
inline AliasedUint32Array& ImmediateInfo::fields() {
307
470
  return fields_;
308
}
309
310
203221
inline uint32_t ImmediateInfo::count() const {
311
203221
  return fields_[kCount];
312
}
313
314
313481
inline uint32_t ImmediateInfo::ref_count() const {
315
313481
  return fields_[kRefCount];
316
}
317
318
63665
inline bool ImmediateInfo::has_outstanding() const {
319
63665
  return fields_[kHasOutstanding] == 1;
320
}
321
322
33418
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
323
33418
  fields_[kRefCount] += increment;
324
33418
}
325
326
217332
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
327
217332
  fields_[kRefCount] -= decrement;
328
217341
}
329
330
470
inline AliasedUint8Array& TickInfo::fields() {
331
470
  return fields_;
332
}
333
334
1446880
inline bool TickInfo::has_tick_scheduled() const {
335
1446880
  return fields_[kHasTickScheduled] == 1;
336
}
337
338
551792
inline bool TickInfo::has_rejection_to_warn() const {
339
551792
  return fields_[kHasRejectionToWarn] == 1;
340
}
341
342
5819
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
343
                                         const ContextInfo& info) {
344
5819
  context->SetAlignedPointerInEmbedderData(
345
5819
      ContextEmbedderIndex::kEnvironment, this);
346
  // Used by Environment::GetCurrent to know that we are on a node context.
347
11638
  context->SetAlignedPointerInEmbedderData(
348
5819
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
349
  // Used to retrieve bindings
350
5819
  context->SetAlignedPointerInEmbedderData(
351
11638
      ContextEmbedderIndex::kBindingListIndex, &(this->bindings_));
352
353
#if HAVE_INSPECTOR
354
5819
  inspector_agent()->ContextCreated(context, info);
355
#endif  // HAVE_INSPECTOR
356
357
5818
  this->async_hooks()->AddContext(context);
358
5819
}
359
360
962029
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
361
962029
  if (UNLIKELY(!isolate->InContext())) return nullptr;
362
1920423
  v8::HandleScope handle_scope(isolate);
363
960098
  return GetCurrent(isolate->GetCurrentContext());
364
}
365
366
6003948
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
367
6003948
  if (UNLIKELY(context.IsEmpty())) {
368
1
    return nullptr;
369
  }
370
6003947
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
371
               ContextEmbedderIndex::kContextTag)) {
372
11
    return nullptr;
373
  }
374
12008518
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
375
                   ContextEmbedderIndex::kContextTag) !=
376
               Environment::kNodeContextTagPtr)) {
377
    return nullptr;
378
  }
379
  return static_cast<Environment*>(
380
6004259
      context->GetAlignedPointerFromEmbedderData(
381
6004259
          ContextEmbedderIndex::kEnvironment));
382
}
383
384
3308059
inline Environment* Environment::GetCurrent(
385
    const v8::FunctionCallbackInfo<v8::Value>& info) {
386
3308059
  return GetCurrent(info.GetIsolate()->GetCurrentContext());
387
}
388
389
template <typename T>
390
1260080
inline Environment* Environment::GetCurrent(
391
    const v8::PropertyCallbackInfo<T>& info) {
392
1260080
  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
696007
inline T* Environment::GetBindingData(
402
    const v8::FunctionCallbackInfo<v8::Value>& info) {
403
696007
  return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
404
}
405
406
template <typename T>
407
696007
inline T* Environment::GetBindingData(v8::Local<v8::Context> context) {
408
  BindingDataStore* map = static_cast<BindingDataStore*>(
409
696007
      context->GetAlignedPointerFromEmbedderData(
410
696007
          ContextEmbedderIndex::kBindingListIndex));
411
  DCHECK_NOT_NULL(map);
412
696007
  auto it = map->find(T::type_name);
413
696006
  if (UNLIKELY(it == map->end())) return nullptr;
414
696005
  T* result = static_cast<T*>(it->second.get());
415
  DCHECK_NOT_NULL(result);
416
  DCHECK_EQ(result->env(), GetCurrent(context));
417
696005
  return result;
418
}
419
420
template <typename T>
421
11520
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
23040
  BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target);
427
  BindingDataStore* map = static_cast<BindingDataStore*>(
428
11520
      context->GetAlignedPointerFromEmbedderData(
429
11520
          ContextEmbedderIndex::kBindingListIndex));
430
  DCHECK_NOT_NULL(map);
431
11520
  auto result = map->emplace(T::type_name, item);
432
11520
  CHECK(result.second);
433
  DCHECK_EQ(GetBindingData<T>(context), item.get());
434
23040
  return item.get();
435
}
436
437
24668144
inline v8::Isolate* Environment::isolate() const {
438
24668144
  return isolate_;
439
}
440
441
5530
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
442
5530
  return ContainerOf(&Environment::timer_handle_, handle);
443
}
444
445
24060
inline uv_timer_t* Environment::timer_handle() {
446
24060
  return &timer_handle_;
447
}
448
449
203218
inline Environment* Environment::from_immediate_check_handle(
450
    uv_check_t* handle) {
451
203218
  return ContainerOf(&Environment::immediate_check_handle_, handle);
452
}
453
454
20828
inline uv_check_t* Environment::immediate_check_handle() {
455
20828
  return &immediate_check_handle_;
456
}
457
458
245759
inline uv_idle_t* Environment::immediate_idle_handle() {
459
245759
  return &immediate_idle_handle_;
460
}
461
462
31241
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
463
                                               HandleCleanupCb cb,
464
                                               void* arg) {
465
31241
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
466
31241
}
467
468
template <typename T, typename OnCloseCallback>
469
32729
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
470
32729
  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
32729
  handle->data = new CloseData { this, callback, handle->data };
482
130960
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
483
65475
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
484
32741
    data->env->handle_cleanup_waiting_--;
485
32739
    handle->data = data->original_data;
486
32739
    data->callback(reinterpret_cast<T*>(handle));
487
32744
  });
488
32734
}
489
490
83535
void Environment::IncreaseWaitingRequestCounter() {
491
83535
  request_waiting_++;
492
83535
}
493
494
83524
void Environment::DecreaseWaitingRequestCounter() {
495
83524
  request_waiting_--;
496
83524
  CHECK_GE(request_waiting_, 0);
497
83524
}
498
499
896983
inline uv_loop_t* Environment::event_loop() const {
500
896983
  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
22901
inline bool Environment::is_in_inspector_console_call() const {
515
22901
  return is_in_inspector_console_call_;
516
}
517
518
45800
inline void Environment::set_is_in_inspector_console_call(bool value) {
519
45800
  is_in_inspector_console_call_ = value;
520
45800
}
521
#endif
522
523
5401290
inline AsyncHooks* Environment::async_hooks() {
524
5401290
  return &async_hooks_;
525
}
526
527
831589
inline ImmediateInfo* Environment::immediate_info() {
528
831589
  return &immediate_info_;
529
}
530
531
723874
inline TickInfo* Environment::tick_info() {
532
723874
  return &tick_info_;
533
}
534
535
53790
inline uint64_t Environment::timer_base() const {
536
53790
  return timer_base_;
537
}
538
539
1273791
inline std::shared_ptr<KVStore> Environment::env_vars() {
540
1273791
  return env_vars_;
541
}
542
543
5656
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
544
5656
  env_vars_ = env_vars;
545
5656
}
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
9509
inline void Environment::set_trace_sync_io(bool value) {
556
9509
  trace_sync_io_ = value;
557
9509
}
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
419
inline void Environment::set_abort_on_uncaught_exception(bool value) {
572
419
  options_->abort_on_uncaught_exception = value;
573
419
}
574
575
500
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
576
500
  return should_abort_on_uncaught_toggle_;
577
}
578
579
305174
inline AliasedInt32Array& Environment::stream_base_state() {
580
305174
  return stream_base_state_;
581
}
582
583
42828
inline uint32_t Environment::get_next_module_id() {
584
42828
  return module_id_counter_++;
585
}
586
2146
inline uint32_t Environment::get_next_script_id() {
587
2146
  return script_id_counter_++;
588
}
589
32148
inline uint32_t Environment::get_next_function_id() {
590
32148
  return function_id_counter_++;
591
}
592
593
87543
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
594
87543
    Environment* env)
595
87543
    : env_(env) {
596
87543
  env_->PushShouldNotAbortOnUncaughtScope();
597
87543
}
598
599
175084
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
600
87542
  Close();
601
87542
}
602
603
87724
void ShouldNotAbortOnUncaughtScope::Close() {
604
87724
  if (env_ != nullptr) {
605
87542
    env_->PopShouldNotAbortOnUncaughtScope();
606
87542
    env_ = nullptr;
607
  }
608
87724
}
609
610
87543
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
611
87543
  should_not_abort_scope_counter_++;
612
87543
}
613
614
87542
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
615
87542
  should_not_abort_scope_counter_--;
616
87542
}
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
387861
inline std::vector<double>* Environment::destroy_async_id_list() {
623
387861
  return &destroy_async_id_list_;
624
}
625
626
219871
inline double Environment::new_async_id() {
627
219871
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
628
219871
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
629
}
630
631
251782
inline double Environment::execution_async_id() {
632
251782
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
633
}
634
635
66080
inline double Environment::trigger_async_id() {
636
66080
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
637
}
638
639
219868
inline double Environment::get_default_trigger_async_id() {
640
  double default_trigger_async_id =
641
219868
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
642
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
643
219868
  if (default_trigger_async_id < 0)
644
174298
    default_trigger_async_id = execution_async_id();
645
219868
  return default_trigger_async_id;
646
}
647
648
59072
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
649
59072
  return options_;
650
}
651
652
15083
inline const std::vector<std::string>& Environment::argv() {
653
15083
  return argv_;
654
}
655
656
5752
inline const std::vector<std::string>& Environment::exec_argv() {
657
5752
  return exec_argv_;
658
}
659
660
10414
inline const std::string& Environment::exec_path() const {
661
10414
  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
5201
inline void Environment::set_coverage_directory(const char* dir) {
682
5201
  coverage_directory_ = std::string(dir);
683
5201
}
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
15666
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
692
15666
  return coverage_connection_.get();
693
}
694
695
5186
inline const std::string& Environment::coverage_directory() const {
696
5186
  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
10614
std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() {
773
10614
  return inspector_host_port_;
774
}
775
776
87309
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
777
87309
  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
56467
void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) {
787
112934
  auto callback = native_immediates_.CreateCallback(std::move(cb), flags);
788
56467
  native_immediates_.Push(std::move(callback));
789
790






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






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

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

2982143
  return can_call_into_js_ && !is_stopping();
824
}
825
826
1019
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
827
1019
  can_call_into_js_ = can_call_into_js;
828
1021
}
829
830
1402651
inline bool Environment::has_run_bootstrapping_code() const {
831
1402651
  return has_run_bootstrapping_code_;
832
}
833
834
5240
inline void Environment::DoneBootstrapping() {
835
5240
  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
5240
  base_object_created_by_bootstrap_ = base_object_count_;
840
5240
}
841
842
19
inline bool Environment::has_serialized_options() const {
843
19
  return has_serialized_options_;
844
}
845
846
5207
inline void Environment::set_has_serialized_options(bool value) {
847
5207
  has_serialized_options_ = value;
848
5207
}
849
850
7058
inline bool Environment::is_main_thread() const {
851
7058
  return worker_context() == nullptr;
852
}
853
854
5207
inline bool Environment::should_not_register_esm_loader() const {
855
5207
  return flags_ & EnvironmentFlags::kNoRegisterESMLoader;
856
}
857
858
12879
inline bool Environment::owns_process_state() const {
859
12879
  return flags_ & EnvironmentFlags::kOwnsProcessState;
860
}
861
862
5232
inline bool Environment::owns_inspector() const {
863
5232
  return flags_ & EnvironmentFlags::kOwnsInspector;
864
}
865
866
106551
inline bool Environment::tracks_unmanaged_fds() const {
867
106551
  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
6155
inline uint64_t Environment::thread_id() const {
887
6155
  return thread_id_;
888
}
889
890
12665
inline worker::Worker* Environment::worker_context() const {
891
12665
  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
678
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
899
678
  sub_worker_contexts_.erase(context);
900
678
}
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
4531469
inline bool Environment::is_stopping() const {
917
4531469
  return is_stopping_.load();
918
}
919
920
4880
inline void Environment::set_stopping(bool value) {
921
4880
  is_stopping_.store(value);
922
4882
}
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
43632
inline performance::PerformanceState* Environment::performance_state() {
938
43632
  return performance_state_.get();
939
}
940
941
5443715
inline IsolateData* Environment::isolate_data() const {
942
5443715
  return isolate_data_;
943
}
944
945
std::unordered_map<char*, std::unique_ptr<v8::BackingStore>>*
946
134630
    Environment::released_allocated_buffers() {
947
134630
  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
1494500
    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
1494500
                                   signature, 0, behavior, side_effect_type);
993
}
994
995
248079
inline void Environment::SetMethod(v8::Local<v8::Object> that,
996
                                   const char* name,
997
                                   v8::FunctionCallback callback) {
998
248079
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
999
  v8::Local<v8::Function> function =
1000
496155
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1001
                          v8::ConstructorBehavior::kThrow,
1002
248078
                          v8::SideEffectType::kHasSideEffect)
1003
496154
          ->GetFunction(context)
1004
248078
          .ToLocalChecked();
1005
  // kInternalized strings are created in the old space.
1006
248078
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1007
  v8::Local<v8::String> name_string =
1008
496159
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1009
496163
  that->Set(context, name_string, function).Check();
1010
248082
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1011
248087
}
1012
1013
104197
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
1014
                                               const char* name,
1015
                                               v8::FunctionCallback callback) {
1016
104197
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1017
  v8::Local<v8::Function> function =
1018
208399
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1019
                          v8::ConstructorBehavior::kThrow,
1020
104202
                          v8::SideEffectType::kHasNoSideEffect)
1021
208404
          ->GetFunction(context)
1022
104202
          .ToLocalChecked();
1023
  // kInternalized strings are created in the old space.
1024
104202
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1025
  v8::Local<v8::String> name_string =
1026
208405
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1027
208405
  that->Set(context, name_string, function).Check();
1028
104202
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1029
104203
}
1030
1031
725000
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1032
                                        const char* name,
1033
                                        v8::FunctionCallback callback) {
1034
725000
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1035
  v8::Local<v8::FunctionTemplate> t =
1036
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1037
724996
                          v8::SideEffectType::kHasSideEffect);
1038
  // kInternalized strings are created in the old space.
1039
725003
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1040
  v8::Local<v8::String> name_string =
1041
1450008
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1042
1450007
  that->PrototypeTemplate()->Set(name_string, t);
1043
725001
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1044
725005
}
1045
1046
170255
inline void Environment::SetProtoMethodNoSideEffect(
1047
    v8::Local<v8::FunctionTemplate> that,
1048
    const char* name,
1049
    v8::FunctionCallback callback) {
1050
170255
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1051
  v8::Local<v8::FunctionTemplate> t =
1052
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1053
170255
                          v8::SideEffectType::kHasNoSideEffect);
1054
  // kInternalized strings are created in the old space.
1055
170254
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1056
  v8::Local<v8::String> name_string =
1057
340508
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1058
340508
  that->PrototypeTemplate()->Set(name_string, t);
1059
170255
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1060
170255
}
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
186495
inline void Environment::SetConstructorFunction(
1078
    v8::Local<v8::Object> that,
1079
    const char* name,
1080
    v8::Local<v8::FunctionTemplate> tmpl,
1081
    SetConstructorFunctionFlag flag) {
1082
186495
  SetConstructorFunction(that, OneByteString(isolate(), name), tmpl, flag);
1083
186496
}
1084
1085
196242
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
196242
  if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME))
1091
191151
    tmpl->SetClassName(name);
1092
392488
  that->Set(
1093
      context(),
1094
      name,
1095
981218
      tmpl->GetFunction(context()).ToLocalChecked()).Check();
1096
196244
}
1097
1098
339864
void Environment::AddCleanupHook(CleanupCallback fn, void* arg) {
1099
679729
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1100
339864
    fn, arg, cleanup_hook_counter_++
1101
339864
  });
1102
  // Make sure there was no existing element with these values.
1103
339865
  CHECK_EQ(insertion_info.second, true);
1104
339865
}
1105
1106
326095
void Environment::RemoveCleanupHook(CleanupCallback fn, void* arg) {
1107
326095
  CleanupHookCallback search { fn, arg, 0 };
1108
326096
  cleanup_hooks_.erase(search);
1109
326124
}
1110
1111
872241
size_t CleanupHookCallback::Hash::operator()(
1112
    const CleanupHookCallback& cb) const {
1113
872241
  return std::hash<void*>()(cb.arg_);
1114
}
1115
1116
433328
bool CleanupHookCallback::Equal::operator()(
1117
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1118

433328
  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
654182
void Environment::modify_base_object_count(int64_t delta) {
1149
654182
  base_object_count_ += delta;
1150
654182
}
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
419
void Environment::set_process_exit_handler(
1166
    std::function<void(Environment*, int)>&& handler) {
1167
419
  process_exit_handler_ = std::move(handler);
1168
419
}
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
72440
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1180
7129387
  PER_ISOLATE_STRING_PROPERTIES(VS)
1181
261018
#undef V
1182
16967
#undef VS
1183
8825
#undef VY
1184
4738
#undef VP
1185
30094
1186
116638
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1187
17341
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1188
22874
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1189
82786
#define V(TypeName, PropertyName)                                             \
1190
83872
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1191
101
    return isolate_data()->PropertyName();                                    \
1192
118
  }
1193
32415
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1194
101052
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1195
3649175
  PER_ISOLATE_STRING_PROPERTIES(VS)
1196
122498
#undef V
1197
2528
#undef VS
1198
12993
#undef VY
1199
3130
#undef VP
1200
43427
1201
92077
#define V(PropertyName, TypeName)                                             \
1202
8504
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1203
15031
    return PersistentToLocal::Strong(PropertyName ## _);                      \
1204
49539
  }                                                                           \
1205
35563
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
1206
68
    PropertyName ## _.Reset(isolate(), value);                                \
1207
68
  }
1208
425871
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1209
1748487
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1210
197659
#undef V
1211
187985
1212
6753332
v8::Local<v8::Context> Environment::context() const {
1213
7099505
  return PersistentToLocal::Strong(context_);
1214
527389
}
1215
89942
1216
74262
}  // namespace node
1217
15813
1218
28348
// These two files depend on each other. Including base_object-inl.h after this
1219
28730
// file is the easiest way to avoid issues with that circular dependency.
1220
51907
#include "base_object-inl.h"
1221
46658
1222
67008
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1223
65616
1224
16190
#endif  // SRC_ENV_INL_H_