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-inl.h"
28 #include "callback_queue-inl.h"
29 #include "env.h"
30 #include "node.h"
31 #include "node_context_data.h"
32 #include "node_internals.h"
33 #include "node_perf_common.h"
34 #include "node_realm-inl.h"
35 #include "util-inl.h"
36 #include "uv.h"
37 #include "v8.h"
38
39 #include <cstddef>
40 #include <cstdint>
41
42 #include <utility>
43
44 namespace node {
45
NoArrayBufferZeroFillScope(IsolateData * isolate_data)46 NoArrayBufferZeroFillScope::NoArrayBufferZeroFillScope(
47 IsolateData* isolate_data)
48 : node_allocator_(isolate_data->node_allocator()) {
49 if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 0;
50 }
51
~NoArrayBufferZeroFillScope()52 NoArrayBufferZeroFillScope::~NoArrayBufferZeroFillScope() {
53 if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 1;
54 }
55
isolate()56 inline v8::Isolate* IsolateData::isolate() const {
57 return isolate_;
58 }
59
event_loop()60 inline uv_loop_t* IsolateData::event_loop() const {
61 return event_loop_;
62 }
63
node_allocator()64 inline NodeArrayBufferAllocator* IsolateData::node_allocator() const {
65 return node_allocator_;
66 }
67
platform()68 inline MultiIsolatePlatform* IsolateData::platform() const {
69 return platform_;
70 }
71
set_worker_context(worker::Worker * context)72 inline void IsolateData::set_worker_context(worker::Worker* context) {
73 CHECK_NULL(worker_context_); // Should be set only once.
74 worker_context_ = context;
75 }
76
worker_context()77 inline worker::Worker* IsolateData::worker_context() const {
78 return worker_context_;
79 }
80
async_wrap_provider(int index)81 inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const {
82 return async_wrap_providers_[index].Get(isolate_);
83 }
84
fields()85 inline AliasedUint32Array& AsyncHooks::fields() {
86 return fields_;
87 }
88
async_id_fields()89 inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
90 return async_id_fields_;
91 }
92
async_ids_stack()93 inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
94 return async_ids_stack_;
95 }
96
js_execution_async_resources()97 v8::Local<v8::Array> AsyncHooks::js_execution_async_resources() {
98 if (UNLIKELY(js_execution_async_resources_.IsEmpty())) {
99 js_execution_async_resources_.Reset(
100 env()->isolate(), v8::Array::New(env()->isolate()));
101 }
102 return PersistentToLocal::Strong(js_execution_async_resources_);
103 }
104
native_execution_async_resource(size_t i)105 v8::Local<v8::Object> AsyncHooks::native_execution_async_resource(size_t i) {
106 if (i >= native_execution_async_resources_.size()) return {};
107 return native_execution_async_resources_[i];
108 }
109
provider_string(int idx)110 inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
111 return env()->isolate_data()->async_wrap_provider(idx);
112 }
113
no_force_checks()114 inline void AsyncHooks::no_force_checks() {
115 fields_[kCheck] -= 1;
116 }
117
env()118 inline Environment* AsyncHooks::env() {
119 return Environment::ForAsyncHooks(this);
120 }
121
ForAsyncHooks(AsyncHooks * hooks)122 Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
123 return ContainerOf(&Environment::async_hooks_, hooks);
124 }
125
async_callback_scope_depth()126 inline size_t Environment::async_callback_scope_depth() const {
127 return async_callback_scope_depth_;
128 }
129
PushAsyncCallbackScope()130 inline void Environment::PushAsyncCallbackScope() {
131 async_callback_scope_depth_++;
132 }
133
PopAsyncCallbackScope()134 inline void Environment::PopAsyncCallbackScope() {
135 async_callback_scope_depth_--;
136 }
137
fields()138 inline AliasedUint32Array& ImmediateInfo::fields() {
139 return fields_;
140 }
141
count()142 inline uint32_t ImmediateInfo::count() const {
143 return fields_[kCount];
144 }
145
ref_count()146 inline uint32_t ImmediateInfo::ref_count() const {
147 return fields_[kRefCount];
148 }
149
has_outstanding()150 inline bool ImmediateInfo::has_outstanding() const {
151 return fields_[kHasOutstanding] == 1;
152 }
153
ref_count_inc(uint32_t increment)154 inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
155 fields_[kRefCount] += increment;
156 }
157
ref_count_dec(uint32_t decrement)158 inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
159 fields_[kRefCount] -= decrement;
160 }
161
fields()162 inline AliasedUint8Array& TickInfo::fields() {
163 return fields_;
164 }
165
has_tick_scheduled()166 inline bool TickInfo::has_tick_scheduled() const {
167 return fields_[kHasTickScheduled] == 1;
168 }
169
has_rejection_to_warn()170 inline bool TickInfo::has_rejection_to_warn() const {
171 return fields_[kHasRejectionToWarn] == 1;
172 }
173
GetCurrent(v8::Isolate * isolate)174 inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
175 if (UNLIKELY(!isolate->InContext())) return nullptr;
176 v8::HandleScope handle_scope(isolate);
177 return GetCurrent(isolate->GetCurrentContext());
178 }
179
GetCurrent(v8::Local<v8::Context> context)180 inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
181 if (UNLIKELY(!ContextEmbedderTag::IsNodeContext(context))) {
182 return nullptr;
183 }
184 return static_cast<Environment*>(
185 context->GetAlignedPointerFromEmbedderData(
186 ContextEmbedderIndex::kEnvironment));
187 }
188
GetCurrent(const v8::FunctionCallbackInfo<v8::Value> & info)189 inline Environment* Environment::GetCurrent(
190 const v8::FunctionCallbackInfo<v8::Value>& info) {
191 return GetCurrent(info.GetIsolate()->GetCurrentContext());
192 }
193
194 template <typename T>
GetCurrent(const v8::PropertyCallbackInfo<T> & info)195 inline Environment* Environment::GetCurrent(
196 const v8::PropertyCallbackInfo<T>& info) {
197 return GetCurrent(info.GetIsolate()->GetCurrentContext());
198 }
199
isolate()200 inline v8::Isolate* Environment::isolate() const {
201 return isolate_;
202 }
203
from_timer_handle(uv_timer_t * handle)204 inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
205 return ContainerOf(&Environment::timer_handle_, handle);
206 }
207
timer_handle()208 inline uv_timer_t* Environment::timer_handle() {
209 return &timer_handle_;
210 }
211
from_immediate_check_handle(uv_check_t * handle)212 inline Environment* Environment::from_immediate_check_handle(
213 uv_check_t* handle) {
214 return ContainerOf(&Environment::immediate_check_handle_, handle);
215 }
216
immediate_check_handle()217 inline uv_check_t* Environment::immediate_check_handle() {
218 return &immediate_check_handle_;
219 }
220
immediate_idle_handle()221 inline uv_idle_t* Environment::immediate_idle_handle() {
222 return &immediate_idle_handle_;
223 }
224
RegisterHandleCleanup(uv_handle_t * handle,HandleCleanupCb cb,void * arg)225 inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
226 HandleCleanupCb cb,
227 void* arg) {
228 handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
229 }
230
231 template <typename T, typename OnCloseCallback>
CloseHandle(T * handle,OnCloseCallback callback)232 inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
233 handle_cleanup_waiting_++;
234 static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
235 static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
236 "T is a libuv handle");
237 static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
238 "T is a libuv handle");
239 struct CloseData {
240 Environment* env;
241 OnCloseCallback callback;
242 void* original_data;
243 };
244 handle->data = new CloseData { this, callback, handle->data };
245 uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
246 std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
247 data->env->handle_cleanup_waiting_--;
248 handle->data = data->original_data;
249 data->callback(reinterpret_cast<T*>(handle));
250 });
251 }
252
IncreaseWaitingRequestCounter()253 void Environment::IncreaseWaitingRequestCounter() {
254 request_waiting_++;
255 }
256
DecreaseWaitingRequestCounter()257 void Environment::DecreaseWaitingRequestCounter() {
258 request_waiting_--;
259 CHECK_GE(request_waiting_, 0);
260 }
261
event_loop()262 inline uv_loop_t* Environment::event_loop() const {
263 return isolate_data()->event_loop();
264 }
265
266 #if HAVE_INSPECTOR
is_in_inspector_console_call()267 inline bool Environment::is_in_inspector_console_call() const {
268 return is_in_inspector_console_call_;
269 }
270
set_is_in_inspector_console_call(bool value)271 inline void Environment::set_is_in_inspector_console_call(bool value) {
272 is_in_inspector_console_call_ = value;
273 }
274 #endif
275
async_hooks()276 inline AsyncHooks* Environment::async_hooks() {
277 return &async_hooks_;
278 }
279
immediate_info()280 inline ImmediateInfo* Environment::immediate_info() {
281 return &immediate_info_;
282 }
283
timeout_info()284 inline AliasedInt32Array& Environment::timeout_info() {
285 return timeout_info_;
286 }
287
tick_info()288 inline TickInfo* Environment::tick_info() {
289 return &tick_info_;
290 }
291
timer_base()292 inline uint64_t Environment::timer_base() const {
293 return timer_base_;
294 }
295
env_vars()296 inline std::shared_ptr<KVStore> Environment::env_vars() {
297 return env_vars_;
298 }
299
set_env_vars(std::shared_ptr<KVStore> env_vars)300 inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
301 env_vars_ = env_vars;
302 }
303
printed_error()304 inline bool Environment::printed_error() const {
305 return printed_error_;
306 }
307
set_printed_error(bool value)308 inline void Environment::set_printed_error(bool value) {
309 printed_error_ = value;
310 }
311
set_trace_sync_io(bool value)312 inline void Environment::set_trace_sync_io(bool value) {
313 trace_sync_io_ = value;
314 }
315
abort_on_uncaught_exception()316 inline bool Environment::abort_on_uncaught_exception() const {
317 return options_->abort_on_uncaught_exception;
318 }
319
set_force_context_aware(bool value)320 inline void Environment::set_force_context_aware(bool value) {
321 options_->force_context_aware = value;
322 }
323
force_context_aware()324 inline bool Environment::force_context_aware() const {
325 return options_->force_context_aware;
326 }
327
set_exiting(bool value)328 inline void Environment::set_exiting(bool value) {
329 exiting_[0] = value ? 1 : 0;
330 }
331
exiting()332 inline AliasedUint32Array& Environment::exiting() {
333 return exiting_;
334 }
335
set_abort_on_uncaught_exception(bool value)336 inline void Environment::set_abort_on_uncaught_exception(bool value) {
337 options_->abort_on_uncaught_exception = value;
338 }
339
should_abort_on_uncaught_toggle()340 inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
341 return should_abort_on_uncaught_toggle_;
342 }
343
stream_base_state()344 inline AliasedInt32Array& Environment::stream_base_state() {
345 return stream_base_state_;
346 }
347
ShouldNotAbortOnUncaughtScope(Environment * env)348 ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
349 Environment* env)
350 : env_(env) {
351 env_->PushShouldNotAbortOnUncaughtScope();
352 }
353
~ShouldNotAbortOnUncaughtScope()354 ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
355 Close();
356 }
357
Close()358 void ShouldNotAbortOnUncaughtScope::Close() {
359 if (env_ != nullptr) {
360 env_->PopShouldNotAbortOnUncaughtScope();
361 env_ = nullptr;
362 }
363 }
364
PushShouldNotAbortOnUncaughtScope()365 inline void Environment::PushShouldNotAbortOnUncaughtScope() {
366 should_not_abort_scope_counter_++;
367 }
368
PopShouldNotAbortOnUncaughtScope()369 inline void Environment::PopShouldNotAbortOnUncaughtScope() {
370 should_not_abort_scope_counter_--;
371 }
372
inside_should_not_abort_on_uncaught_scope()373 inline bool Environment::inside_should_not_abort_on_uncaught_scope() const {
374 return should_not_abort_scope_counter_ > 0;
375 }
376
destroy_async_id_list()377 inline std::vector<double>* Environment::destroy_async_id_list() {
378 return &destroy_async_id_list_;
379 }
380
builtin_loader()381 inline builtins::BuiltinLoader* Environment::builtin_loader() {
382 return &builtin_loader_;
383 }
384
new_async_id()385 inline double Environment::new_async_id() {
386 async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
387 return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
388 }
389
execution_async_id()390 inline double Environment::execution_async_id() {
391 return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
392 }
393
trigger_async_id()394 inline double Environment::trigger_async_id() {
395 return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
396 }
397
get_default_trigger_async_id()398 inline double Environment::get_default_trigger_async_id() {
399 double default_trigger_async_id =
400 async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
401 // If defaultTriggerAsyncId isn't set, use the executionAsyncId
402 if (default_trigger_async_id < 0)
403 default_trigger_async_id = execution_async_id();
404 return default_trigger_async_id;
405 }
406
options()407 inline std::shared_ptr<EnvironmentOptions> Environment::options() {
408 return options_;
409 }
410
argv()411 inline const std::vector<std::string>& Environment::argv() {
412 return argv_;
413 }
414
exec_argv()415 inline const std::vector<std::string>& Environment::exec_argv() {
416 return exec_argv_;
417 }
418
exec_path()419 inline const std::string& Environment::exec_path() const {
420 return exec_path_;
421 }
422
423 #if HAVE_INSPECTOR
set_coverage_directory(const char * dir)424 inline void Environment::set_coverage_directory(const char* dir) {
425 coverage_directory_ = std::string(dir);
426 }
427
set_coverage_connection(std::unique_ptr<profiler::V8CoverageConnection> connection)428 inline void Environment::set_coverage_connection(
429 std::unique_ptr<profiler::V8CoverageConnection> connection) {
430 CHECK_NULL(coverage_connection_);
431 std::swap(coverage_connection_, connection);
432 }
433
coverage_connection()434 inline profiler::V8CoverageConnection* Environment::coverage_connection() {
435 return coverage_connection_.get();
436 }
437
coverage_directory()438 inline const std::string& Environment::coverage_directory() const {
439 return coverage_directory_;
440 }
441
set_cpu_profiler_connection(std::unique_ptr<profiler::V8CpuProfilerConnection> connection)442 inline void Environment::set_cpu_profiler_connection(
443 std::unique_ptr<profiler::V8CpuProfilerConnection> connection) {
444 CHECK_NULL(cpu_profiler_connection_);
445 std::swap(cpu_profiler_connection_, connection);
446 }
447
448 inline profiler::V8CpuProfilerConnection*
cpu_profiler_connection()449 Environment::cpu_profiler_connection() {
450 return cpu_profiler_connection_.get();
451 }
452
set_cpu_prof_interval(uint64_t interval)453 inline void Environment::set_cpu_prof_interval(uint64_t interval) {
454 cpu_prof_interval_ = interval;
455 }
456
cpu_prof_interval()457 inline uint64_t Environment::cpu_prof_interval() const {
458 return cpu_prof_interval_;
459 }
460
set_cpu_prof_name(const std::string & name)461 inline void Environment::set_cpu_prof_name(const std::string& name) {
462 cpu_prof_name_ = name;
463 }
464
cpu_prof_name()465 inline const std::string& Environment::cpu_prof_name() const {
466 return cpu_prof_name_;
467 }
468
set_cpu_prof_dir(const std::string & dir)469 inline void Environment::set_cpu_prof_dir(const std::string& dir) {
470 cpu_prof_dir_ = dir;
471 }
472
cpu_prof_dir()473 inline const std::string& Environment::cpu_prof_dir() const {
474 return cpu_prof_dir_;
475 }
476
set_heap_profiler_connection(std::unique_ptr<profiler::V8HeapProfilerConnection> connection)477 inline void Environment::set_heap_profiler_connection(
478 std::unique_ptr<profiler::V8HeapProfilerConnection> connection) {
479 CHECK_NULL(heap_profiler_connection_);
480 std::swap(heap_profiler_connection_, connection);
481 }
482
483 inline profiler::V8HeapProfilerConnection*
heap_profiler_connection()484 Environment::heap_profiler_connection() {
485 return heap_profiler_connection_.get();
486 }
487
set_heap_prof_name(const std::string & name)488 inline void Environment::set_heap_prof_name(const std::string& name) {
489 heap_prof_name_ = name;
490 }
491
heap_prof_name()492 inline const std::string& Environment::heap_prof_name() const {
493 return heap_prof_name_;
494 }
495
set_heap_prof_dir(const std::string & dir)496 inline void Environment::set_heap_prof_dir(const std::string& dir) {
497 heap_prof_dir_ = dir;
498 }
499
heap_prof_dir()500 inline const std::string& Environment::heap_prof_dir() const {
501 return heap_prof_dir_;
502 }
503
set_heap_prof_interval(uint64_t interval)504 inline void Environment::set_heap_prof_interval(uint64_t interval) {
505 heap_prof_interval_ = interval;
506 }
507
heap_prof_interval()508 inline uint64_t Environment::heap_prof_interval() const {
509 return heap_prof_interval_;
510 }
511
512 #endif // HAVE_INSPECTOR
513
514 inline
inspector_host_port()515 std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() {
516 return inspector_host_port_;
517 }
518
options()519 inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
520 return options_;
521 }
522
set_options(std::shared_ptr<PerIsolateOptions> options)523 inline void IsolateData::set_options(
524 std::shared_ptr<PerIsolateOptions> options) {
525 options_ = std::move(options);
526 }
527
528 template <typename Fn>
SetImmediate(Fn && cb,CallbackFlags::Flags flags)529 void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) {
530 auto callback = native_immediates_.CreateCallback(std::move(cb), flags);
531 native_immediates_.Push(std::move(callback));
532
533 if (flags & CallbackFlags::kRefed) {
534 if (immediate_info()->ref_count() == 0)
535 ToggleImmediateRef(true);
536 immediate_info()->ref_count_inc(1);
537 }
538 }
539
540 template <typename Fn>
SetImmediateThreadsafe(Fn && cb,CallbackFlags::Flags flags)541 void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) {
542 auto callback = native_immediates_threadsafe_.CreateCallback(
543 std::move(cb), flags);
544 {
545 Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
546 native_immediates_threadsafe_.Push(std::move(callback));
547 if (task_queues_async_initialized_)
548 uv_async_send(&task_queues_async_);
549 }
550 }
551
552 template <typename Fn>
RequestInterrupt(Fn && cb)553 void Environment::RequestInterrupt(Fn&& cb) {
554 auto callback = native_immediates_interrupts_.CreateCallback(
555 std::move(cb), CallbackFlags::kRefed);
556 {
557 Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
558 native_immediates_interrupts_.Push(std::move(callback));
559 if (task_queues_async_initialized_)
560 uv_async_send(&task_queues_async_);
561 }
562 RequestInterruptFromV8();
563 }
564
can_call_into_js()565 inline bool Environment::can_call_into_js() const {
566 return can_call_into_js_ && !is_stopping();
567 }
568
set_can_call_into_js(bool can_call_into_js)569 inline void Environment::set_can_call_into_js(bool can_call_into_js) {
570 can_call_into_js_ = can_call_into_js;
571 }
572
has_run_bootstrapping_code()573 inline bool Environment::has_run_bootstrapping_code() const {
574 return principal_realm_->has_run_bootstrapping_code();
575 }
576
has_serialized_options()577 inline bool Environment::has_serialized_options() const {
578 return has_serialized_options_;
579 }
580
set_has_serialized_options(bool value)581 inline void Environment::set_has_serialized_options(bool value) {
582 has_serialized_options_ = value;
583 }
584
is_main_thread()585 inline bool Environment::is_main_thread() const {
586 return worker_context() == nullptr;
587 }
588
no_native_addons()589 inline bool Environment::no_native_addons() const {
590 return (flags_ & EnvironmentFlags::kNoNativeAddons) ||
591 !options_->allow_native_addons;
592 }
593
should_not_register_esm_loader()594 inline bool Environment::should_not_register_esm_loader() const {
595 return flags_ & EnvironmentFlags::kNoRegisterESMLoader;
596 }
597
owns_process_state()598 inline bool Environment::owns_process_state() const {
599 return flags_ & EnvironmentFlags::kOwnsProcessState;
600 }
601
owns_inspector()602 inline bool Environment::owns_inspector() const {
603 return flags_ & EnvironmentFlags::kOwnsInspector;
604 }
605
should_create_inspector()606 inline bool Environment::should_create_inspector() const {
607 return (flags_ & EnvironmentFlags::kNoCreateInspector) == 0 &&
608 !options_->test_runner && !options_->watch_mode;
609 }
610
tracks_unmanaged_fds()611 inline bool Environment::tracks_unmanaged_fds() const {
612 return flags_ & EnvironmentFlags::kTrackUnmanagedFds;
613 }
614
hide_console_windows()615 inline bool Environment::hide_console_windows() const {
616 return flags_ & EnvironmentFlags::kHideConsoleWindows;
617 }
618
no_global_search_paths()619 inline bool Environment::no_global_search_paths() const {
620 return (flags_ & EnvironmentFlags::kNoGlobalSearchPaths) ||
621 !options_->global_search_paths;
622 }
623
no_browser_globals()624 inline bool Environment::no_browser_globals() const {
625 // configure --no-browser-globals
626 #ifdef NODE_NO_BROWSER_GLOBALS
627 return true;
628 #else
629 return flags_ & EnvironmentFlags::kNoBrowserGlobals;
630 #endif
631 }
632
filehandle_close_warning()633 bool Environment::filehandle_close_warning() const {
634 return emit_filehandle_warning_;
635 }
636
set_filehandle_close_warning(bool on)637 void Environment::set_filehandle_close_warning(bool on) {
638 emit_filehandle_warning_ = on;
639 }
640
set_source_maps_enabled(bool on)641 void Environment::set_source_maps_enabled(bool on) {
642 source_maps_enabled_ = on;
643 }
644
source_maps_enabled()645 bool Environment::source_maps_enabled() const {
646 return source_maps_enabled_;
647 }
648
thread_id()649 inline uint64_t Environment::thread_id() const {
650 return thread_id_;
651 }
652
worker_context()653 inline worker::Worker* Environment::worker_context() const {
654 return isolate_data()->worker_context();
655 }
656
add_sub_worker_context(worker::Worker * context)657 inline void Environment::add_sub_worker_context(worker::Worker* context) {
658 sub_worker_contexts_.insert(context);
659 }
660
remove_sub_worker_context(worker::Worker * context)661 inline void Environment::remove_sub_worker_context(worker::Worker* context) {
662 sub_worker_contexts_.erase(context);
663 }
664
665 template <typename Fn>
ForEachWorker(Fn && iterator)666 inline void Environment::ForEachWorker(Fn&& iterator) {
667 for (worker::Worker* w : sub_worker_contexts_) iterator(w);
668 }
669
is_stopping()670 inline bool Environment::is_stopping() const {
671 return is_stopping_.load();
672 }
673
set_stopping(bool value)674 inline void Environment::set_stopping(bool value) {
675 is_stopping_.store(value);
676 }
677
extra_linked_bindings()678 inline std::list<node_module>* Environment::extra_linked_bindings() {
679 return &extra_linked_bindings_;
680 }
681
extra_linked_bindings_head()682 inline node_module* Environment::extra_linked_bindings_head() {
683 return extra_linked_bindings_.size() > 0 ?
684 &extra_linked_bindings_.front() : nullptr;
685 }
686
extra_linked_bindings_tail()687 inline node_module* Environment::extra_linked_bindings_tail() {
688 return extra_linked_bindings_.size() > 0 ?
689 &extra_linked_bindings_.back() : nullptr;
690 }
691
extra_linked_bindings_mutex()692 inline const Mutex& Environment::extra_linked_bindings_mutex() const {
693 return extra_linked_bindings_mutex_;
694 }
695
performance_state()696 inline performance::PerformanceState* Environment::performance_state() {
697 return performance_state_.get();
698 }
699
isolate_data()700 inline IsolateData* Environment::isolate_data() const {
701 return isolate_data_;
702 }
703
704 template <typename T>
ForEachRealm(T && iterator)705 inline void Environment::ForEachRealm(T&& iterator) const {
706 // TODO(legendecas): iterate over more realms bound to the environment.
707 iterator(principal_realm());
708 }
709
ThrowError(const char * errmsg)710 inline void Environment::ThrowError(const char* errmsg) {
711 ThrowError(v8::Exception::Error, errmsg);
712 }
713
ThrowTypeError(const char * errmsg)714 inline void Environment::ThrowTypeError(const char* errmsg) {
715 ThrowError(v8::Exception::TypeError, errmsg);
716 }
717
ThrowRangeError(const char * errmsg)718 inline void Environment::ThrowRangeError(const char* errmsg) {
719 ThrowError(v8::Exception::RangeError, errmsg);
720 }
721
ThrowError(v8::Local<v8::Value> (* fun)(v8::Local<v8::String>),const char * errmsg)722 inline void Environment::ThrowError(
723 v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
724 const char* errmsg) {
725 v8::HandleScope handle_scope(isolate());
726 isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
727 }
728
ThrowErrnoException(int errorno,const char * syscall,const char * message,const char * path)729 inline void Environment::ThrowErrnoException(int errorno,
730 const char* syscall,
731 const char* message,
732 const char* path) {
733 isolate()->ThrowException(
734 ErrnoException(isolate(), errorno, syscall, message, path));
735 }
736
ThrowUVException(int errorno,const char * syscall,const char * message,const char * path,const char * dest)737 inline void Environment::ThrowUVException(int errorno,
738 const char* syscall,
739 const char* message,
740 const char* path,
741 const char* dest) {
742 isolate()->ThrowException(
743 UVException(isolate(), errorno, syscall, message, path, dest));
744 }
745
AddCleanupHook(CleanupQueue::Callback fn,void * arg)746 void Environment::AddCleanupHook(CleanupQueue::Callback fn, void* arg) {
747 cleanup_queue_.Add(fn, arg);
748 }
749
RemoveCleanupHook(CleanupQueue::Callback fn,void * arg)750 void Environment::RemoveCleanupHook(CleanupQueue::Callback fn, void* arg) {
751 cleanup_queue_.Remove(fn, arg);
752 }
753
set_process_exit_handler(std::function<void (Environment *,int)> && handler)754 void Environment::set_process_exit_handler(
755 std::function<void(Environment*, int)>&& handler) {
756 process_exit_handler_ = std::move(handler);
757 }
758
759 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
760 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
761 #define VS(PropertyName, StringValue) V(v8::String, PropertyName)
762 #define V(TypeName, PropertyName) \
763 inline \
764 v8::Local<TypeName> IsolateData::PropertyName() const { \
765 return PropertyName ## _ .Get(isolate_); \
766 }
767 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)768 PER_ISOLATE_SYMBOL_PROPERTIES(VY)
769 PER_ISOLATE_STRING_PROPERTIES(VS)
770 #undef V
771 #undef VS
772 #undef VY
773 #undef VP
774
775 #define VM(PropertyName) V(PropertyName##_binding, v8::FunctionTemplate)
776 #define V(PropertyName, TypeName) \
777 inline v8::Local<TypeName> IsolateData::PropertyName() const { \
778 return PropertyName##_.Get(isolate_); \
779 } \
780 inline void IsolateData::set_##PropertyName(v8::Local<TypeName> value) { \
781 PropertyName##_.Set(isolate_, value); \
782 }
783 PER_ISOLATE_TEMPLATE_PROPERTIES(V)
784 NODE_BINDINGS_WITH_PER_ISOLATE_INIT(VM)
785 #undef V
786 #undef VM
787
788 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
789 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
790 #define VS(PropertyName, StringValue) V(v8::String, PropertyName)
791 #define V(TypeName, PropertyName) \
792 inline v8::Local<TypeName> Environment::PropertyName() const { \
793 return isolate_data()->PropertyName(); \
794 }
795 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
796 PER_ISOLATE_SYMBOL_PROPERTIES(VY)
797 PER_ISOLATE_STRING_PROPERTIES(VS)
798 #undef V
799 #undef VS
800 #undef VY
801 #undef VP
802
803 #define V(PropertyName, TypeName) \
804 inline v8::Local<TypeName> Environment::PropertyName() const { \
805 return isolate_data()->PropertyName(); \
806 } \
807 inline void Environment::set_##PropertyName(v8::Local<TypeName> value) { \
808 DCHECK(isolate_data()->PropertyName().IsEmpty()); \
809 isolate_data()->set_##PropertyName(value); \
810 }
811 PER_ISOLATE_TEMPLATE_PROPERTIES(V)
812 #undef V
813
814 #define V(PropertyName, TypeName) \
815 inline v8::Local<TypeName> Environment::PropertyName() const { \
816 DCHECK_NOT_NULL(principal_realm_); \
817 return principal_realm_->PropertyName(); \
818 } \
819 inline void Environment::set_##PropertyName(v8::Local<TypeName> value) { \
820 DCHECK_NOT_NULL(principal_realm_); \
821 principal_realm_->set_##PropertyName(value); \
822 }
823 PER_REALM_STRONG_PERSISTENT_VALUES(V)
824 #undef V
825
826 v8::Local<v8::Context> Environment::context() const {
827 return principal_realm()->context();
828 }
829
principal_realm()830 Realm* Environment::principal_realm() const {
831 return principal_realm_.get();
832 }
833
set_heap_snapshot_near_heap_limit(uint32_t limit)834 inline void Environment::set_heap_snapshot_near_heap_limit(uint32_t limit) {
835 heap_snapshot_near_heap_limit_ = limit;
836 }
837
is_in_heapsnapshot_heap_limit_callback()838 inline bool Environment::is_in_heapsnapshot_heap_limit_callback() const {
839 return is_in_heapsnapshot_heap_limit_callback_;
840 }
841
AddHeapSnapshotNearHeapLimitCallback()842 inline void Environment::AddHeapSnapshotNearHeapLimitCallback() {
843 DCHECK(!heapsnapshot_near_heap_limit_callback_added_);
844 heapsnapshot_near_heap_limit_callback_added_ = true;
845 isolate_->AddNearHeapLimitCallback(Environment::NearHeapLimitCallback, this);
846 }
847
RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit)848 inline void Environment::RemoveHeapSnapshotNearHeapLimitCallback(
849 size_t heap_limit) {
850 DCHECK(heapsnapshot_near_heap_limit_callback_added_);
851 heapsnapshot_near_heap_limit_callback_added_ = false;
852 isolate_->RemoveNearHeapLimitCallback(Environment::NearHeapLimitCallback,
853 heap_limit);
854 }
855
856 } // namespace node
857
858 // These two files depend on each other. Including base_object-inl.h after this
859 // file is the easiest way to avoid issues with that circular dependency.
860 #include "base_object-inl.h"
861
862 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
863
864 #endif // SRC_ENV_INL_H_
865