• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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 
get_next_module_id()348 inline uint32_t Environment::get_next_module_id() {
349   return module_id_counter_++;
350 }
get_next_script_id()351 inline uint32_t Environment::get_next_script_id() {
352   return script_id_counter_++;
353 }
get_next_function_id()354 inline uint32_t Environment::get_next_function_id() {
355   return function_id_counter_++;
356 }
357 
ShouldNotAbortOnUncaughtScope(Environment * env)358 ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
359     Environment* env)
360     : env_(env) {
361   env_->PushShouldNotAbortOnUncaughtScope();
362 }
363 
~ShouldNotAbortOnUncaughtScope()364 ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
365   Close();
366 }
367 
Close()368 void ShouldNotAbortOnUncaughtScope::Close() {
369   if (env_ != nullptr) {
370     env_->PopShouldNotAbortOnUncaughtScope();
371     env_ = nullptr;
372   }
373 }
374 
PushShouldNotAbortOnUncaughtScope()375 inline void Environment::PushShouldNotAbortOnUncaughtScope() {
376   should_not_abort_scope_counter_++;
377 }
378 
PopShouldNotAbortOnUncaughtScope()379 inline void Environment::PopShouldNotAbortOnUncaughtScope() {
380   should_not_abort_scope_counter_--;
381 }
382 
inside_should_not_abort_on_uncaught_scope()383 inline bool Environment::inside_should_not_abort_on_uncaught_scope() const {
384   return should_not_abort_scope_counter_ > 0;
385 }
386 
destroy_async_id_list()387 inline std::vector<double>* Environment::destroy_async_id_list() {
388   return &destroy_async_id_list_;
389 }
390 
new_async_id()391 inline double Environment::new_async_id() {
392   async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
393   return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
394 }
395 
execution_async_id()396 inline double Environment::execution_async_id() {
397   return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
398 }
399 
trigger_async_id()400 inline double Environment::trigger_async_id() {
401   return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
402 }
403 
get_default_trigger_async_id()404 inline double Environment::get_default_trigger_async_id() {
405   double default_trigger_async_id =
406     async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
407   // If defaultTriggerAsyncId isn't set, use the executionAsyncId
408   if (default_trigger_async_id < 0)
409     default_trigger_async_id = execution_async_id();
410   return default_trigger_async_id;
411 }
412 
options()413 inline std::shared_ptr<EnvironmentOptions> Environment::options() {
414   return options_;
415 }
416 
argv()417 inline const std::vector<std::string>& Environment::argv() {
418   return argv_;
419 }
420 
exec_argv()421 inline const std::vector<std::string>& Environment::exec_argv() {
422   return exec_argv_;
423 }
424 
exec_path()425 inline const std::string& Environment::exec_path() const {
426   return exec_path_;
427 }
428 
429 #if HAVE_INSPECTOR
set_coverage_directory(const char * dir)430 inline void Environment::set_coverage_directory(const char* dir) {
431   coverage_directory_ = std::string(dir);
432 }
433 
set_coverage_connection(std::unique_ptr<profiler::V8CoverageConnection> connection)434 inline void Environment::set_coverage_connection(
435     std::unique_ptr<profiler::V8CoverageConnection> connection) {
436   CHECK_NULL(coverage_connection_);
437   std::swap(coverage_connection_, connection);
438 }
439 
coverage_connection()440 inline profiler::V8CoverageConnection* Environment::coverage_connection() {
441   return coverage_connection_.get();
442 }
443 
coverage_directory()444 inline const std::string& Environment::coverage_directory() const {
445   return coverage_directory_;
446 }
447 
set_cpu_profiler_connection(std::unique_ptr<profiler::V8CpuProfilerConnection> connection)448 inline void Environment::set_cpu_profiler_connection(
449     std::unique_ptr<profiler::V8CpuProfilerConnection> connection) {
450   CHECK_NULL(cpu_profiler_connection_);
451   std::swap(cpu_profiler_connection_, connection);
452 }
453 
454 inline profiler::V8CpuProfilerConnection*
cpu_profiler_connection()455 Environment::cpu_profiler_connection() {
456   return cpu_profiler_connection_.get();
457 }
458 
set_cpu_prof_interval(uint64_t interval)459 inline void Environment::set_cpu_prof_interval(uint64_t interval) {
460   cpu_prof_interval_ = interval;
461 }
462 
cpu_prof_interval()463 inline uint64_t Environment::cpu_prof_interval() const {
464   return cpu_prof_interval_;
465 }
466 
set_cpu_prof_name(const std::string & name)467 inline void Environment::set_cpu_prof_name(const std::string& name) {
468   cpu_prof_name_ = name;
469 }
470 
cpu_prof_name()471 inline const std::string& Environment::cpu_prof_name() const {
472   return cpu_prof_name_;
473 }
474 
set_cpu_prof_dir(const std::string & dir)475 inline void Environment::set_cpu_prof_dir(const std::string& dir) {
476   cpu_prof_dir_ = dir;
477 }
478 
cpu_prof_dir()479 inline const std::string& Environment::cpu_prof_dir() const {
480   return cpu_prof_dir_;
481 }
482 
set_heap_profiler_connection(std::unique_ptr<profiler::V8HeapProfilerConnection> connection)483 inline void Environment::set_heap_profiler_connection(
484     std::unique_ptr<profiler::V8HeapProfilerConnection> connection) {
485   CHECK_NULL(heap_profiler_connection_);
486   std::swap(heap_profiler_connection_, connection);
487 }
488 
489 inline profiler::V8HeapProfilerConnection*
heap_profiler_connection()490 Environment::heap_profiler_connection() {
491   return heap_profiler_connection_.get();
492 }
493 
set_heap_prof_name(const std::string & name)494 inline void Environment::set_heap_prof_name(const std::string& name) {
495   heap_prof_name_ = name;
496 }
497 
heap_prof_name()498 inline const std::string& Environment::heap_prof_name() const {
499   return heap_prof_name_;
500 }
501 
set_heap_prof_dir(const std::string & dir)502 inline void Environment::set_heap_prof_dir(const std::string& dir) {
503   heap_prof_dir_ = dir;
504 }
505 
heap_prof_dir()506 inline const std::string& Environment::heap_prof_dir() const {
507   return heap_prof_dir_;
508 }
509 
set_heap_prof_interval(uint64_t interval)510 inline void Environment::set_heap_prof_interval(uint64_t interval) {
511   heap_prof_interval_ = interval;
512 }
513 
heap_prof_interval()514 inline uint64_t Environment::heap_prof_interval() const {
515   return heap_prof_interval_;
516 }
517 
518 #endif  // HAVE_INSPECTOR
519 
520 inline
inspector_host_port()521 std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() {
522   return inspector_host_port_;
523 }
524 
options()525 inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
526   return options_;
527 }
528 
set_options(std::shared_ptr<PerIsolateOptions> options)529 inline void IsolateData::set_options(
530     std::shared_ptr<PerIsolateOptions> options) {
531   options_ = std::move(options);
532 }
533 
534 template <typename Fn>
SetImmediate(Fn && cb,CallbackFlags::Flags flags)535 void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) {
536   auto callback = native_immediates_.CreateCallback(std::move(cb), flags);
537   native_immediates_.Push(std::move(callback));
538 
539   if (flags & CallbackFlags::kRefed) {
540     if (immediate_info()->ref_count() == 0)
541       ToggleImmediateRef(true);
542     immediate_info()->ref_count_inc(1);
543   }
544 }
545 
546 template <typename Fn>
SetImmediateThreadsafe(Fn && cb,CallbackFlags::Flags flags)547 void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) {
548   auto callback = native_immediates_threadsafe_.CreateCallback(
549       std::move(cb), flags);
550   {
551     Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
552     native_immediates_threadsafe_.Push(std::move(callback));
553     if (task_queues_async_initialized_)
554       uv_async_send(&task_queues_async_);
555   }
556 }
557 
558 template <typename Fn>
RequestInterrupt(Fn && cb)559 void Environment::RequestInterrupt(Fn&& cb) {
560   auto callback = native_immediates_interrupts_.CreateCallback(
561       std::move(cb), CallbackFlags::kRefed);
562   {
563     Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
564     native_immediates_interrupts_.Push(std::move(callback));
565     if (task_queues_async_initialized_)
566       uv_async_send(&task_queues_async_);
567   }
568   RequestInterruptFromV8();
569 }
570 
can_call_into_js()571 inline bool Environment::can_call_into_js() const {
572   return can_call_into_js_ && !is_stopping();
573 }
574 
set_can_call_into_js(bool can_call_into_js)575 inline void Environment::set_can_call_into_js(bool can_call_into_js) {
576   can_call_into_js_ = can_call_into_js;
577 }
578 
has_run_bootstrapping_code()579 inline bool Environment::has_run_bootstrapping_code() const {
580   return principal_realm_->has_run_bootstrapping_code();
581 }
582 
has_serialized_options()583 inline bool Environment::has_serialized_options() const {
584   return has_serialized_options_;
585 }
586 
set_has_serialized_options(bool value)587 inline void Environment::set_has_serialized_options(bool value) {
588   has_serialized_options_ = value;
589 }
590 
is_main_thread()591 inline bool Environment::is_main_thread() const {
592   return worker_context() == nullptr;
593 }
594 
no_native_addons()595 inline bool Environment::no_native_addons() const {
596   return (flags_ & EnvironmentFlags::kNoNativeAddons) ||
597           !options_->allow_native_addons;
598 }
599 
should_not_register_esm_loader()600 inline bool Environment::should_not_register_esm_loader() const {
601   return flags_ & EnvironmentFlags::kNoRegisterESMLoader;
602 }
603 
owns_process_state()604 inline bool Environment::owns_process_state() const {
605   return flags_ & EnvironmentFlags::kOwnsProcessState;
606 }
607 
owns_inspector()608 inline bool Environment::owns_inspector() const {
609   return flags_ & EnvironmentFlags::kOwnsInspector;
610 }
611 
should_create_inspector()612 inline bool Environment::should_create_inspector() const {
613   return (flags_ & EnvironmentFlags::kNoCreateInspector) == 0 &&
614          !options_->test_runner && !options_->watch_mode;
615 }
616 
tracks_unmanaged_fds()617 inline bool Environment::tracks_unmanaged_fds() const {
618   return flags_ & EnvironmentFlags::kTrackUnmanagedFds;
619 }
620 
hide_console_windows()621 inline bool Environment::hide_console_windows() const {
622   return flags_ & EnvironmentFlags::kHideConsoleWindows;
623 }
624 
no_global_search_paths()625 inline bool Environment::no_global_search_paths() const {
626   return (flags_ & EnvironmentFlags::kNoGlobalSearchPaths) ||
627          !options_->global_search_paths;
628 }
629 
no_browser_globals()630 inline bool Environment::no_browser_globals() const {
631   // configure --no-browser-globals
632 #ifdef NODE_NO_BROWSER_GLOBALS
633   return true;
634 #else
635   return flags_ & EnvironmentFlags::kNoBrowserGlobals;
636 #endif
637 }
638 
filehandle_close_warning()639 bool Environment::filehandle_close_warning() const {
640   return emit_filehandle_warning_;
641 }
642 
set_filehandle_close_warning(bool on)643 void Environment::set_filehandle_close_warning(bool on) {
644   emit_filehandle_warning_ = on;
645 }
646 
set_source_maps_enabled(bool on)647 void Environment::set_source_maps_enabled(bool on) {
648   source_maps_enabled_ = on;
649 }
650 
source_maps_enabled()651 bool Environment::source_maps_enabled() const {
652   return source_maps_enabled_;
653 }
654 
thread_id()655 inline uint64_t Environment::thread_id() const {
656   return thread_id_;
657 }
658 
worker_context()659 inline worker::Worker* Environment::worker_context() const {
660   return isolate_data()->worker_context();
661 }
662 
add_sub_worker_context(worker::Worker * context)663 inline void Environment::add_sub_worker_context(worker::Worker* context) {
664   sub_worker_contexts_.insert(context);
665 }
666 
remove_sub_worker_context(worker::Worker * context)667 inline void Environment::remove_sub_worker_context(worker::Worker* context) {
668   sub_worker_contexts_.erase(context);
669 }
670 
671 template <typename Fn>
ForEachWorker(Fn && iterator)672 inline void Environment::ForEachWorker(Fn&& iterator) {
673   for (worker::Worker* w : sub_worker_contexts_) iterator(w);
674 }
675 
is_stopping()676 inline bool Environment::is_stopping() const {
677   return is_stopping_.load();
678 }
679 
set_stopping(bool value)680 inline void Environment::set_stopping(bool value) {
681   is_stopping_.store(value);
682 }
683 
extra_linked_bindings()684 inline std::list<node_module>* Environment::extra_linked_bindings() {
685   return &extra_linked_bindings_;
686 }
687 
extra_linked_bindings_head()688 inline node_module* Environment::extra_linked_bindings_head() {
689   return extra_linked_bindings_.size() > 0 ?
690       &extra_linked_bindings_.front() : nullptr;
691 }
692 
extra_linked_bindings_tail()693 inline node_module* Environment::extra_linked_bindings_tail() {
694   return extra_linked_bindings_.size() > 0 ?
695       &extra_linked_bindings_.back() : nullptr;
696 }
697 
extra_linked_bindings_mutex()698 inline const Mutex& Environment::extra_linked_bindings_mutex() const {
699   return extra_linked_bindings_mutex_;
700 }
701 
performance_state()702 inline performance::PerformanceState* Environment::performance_state() {
703   return performance_state_.get();
704 }
705 
isolate_data()706 inline IsolateData* Environment::isolate_data() const {
707   return isolate_data_;
708 }
709 
710 template <typename T>
ForEachRealm(T && iterator)711 inline void Environment::ForEachRealm(T&& iterator) const {
712   // TODO(legendecas): iterate over more realms bound to the environment.
713   iterator(principal_realm());
714 }
715 
ThrowError(const char * errmsg)716 inline void Environment::ThrowError(const char* errmsg) {
717   ThrowError(v8::Exception::Error, errmsg);
718 }
719 
ThrowTypeError(const char * errmsg)720 inline void Environment::ThrowTypeError(const char* errmsg) {
721   ThrowError(v8::Exception::TypeError, errmsg);
722 }
723 
ThrowRangeError(const char * errmsg)724 inline void Environment::ThrowRangeError(const char* errmsg) {
725   ThrowError(v8::Exception::RangeError, errmsg);
726 }
727 
ThrowError(v8::Local<v8::Value> (* fun)(v8::Local<v8::String>),const char * errmsg)728 inline void Environment::ThrowError(
729     v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
730     const char* errmsg) {
731   v8::HandleScope handle_scope(isolate());
732   isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
733 }
734 
ThrowErrnoException(int errorno,const char * syscall,const char * message,const char * path)735 inline void Environment::ThrowErrnoException(int errorno,
736                                              const char* syscall,
737                                              const char* message,
738                                              const char* path) {
739   isolate()->ThrowException(
740       ErrnoException(isolate(), errorno, syscall, message, path));
741 }
742 
ThrowUVException(int errorno,const char * syscall,const char * message,const char * path,const char * dest)743 inline void Environment::ThrowUVException(int errorno,
744                                           const char* syscall,
745                                           const char* message,
746                                           const char* path,
747                                           const char* dest) {
748   isolate()->ThrowException(
749       UVException(isolate(), errorno, syscall, message, path, dest));
750 }
751 
AddCleanupHook(CleanupQueue::Callback fn,void * arg)752 void Environment::AddCleanupHook(CleanupQueue::Callback fn, void* arg) {
753   cleanup_queue_.Add(fn, arg);
754 }
755 
RemoveCleanupHook(CleanupQueue::Callback fn,void * arg)756 void Environment::RemoveCleanupHook(CleanupQueue::Callback fn, void* arg) {
757   cleanup_queue_.Remove(fn, arg);
758 }
759 
set_process_exit_handler(std::function<void (Environment *,int)> && handler)760 void Environment::set_process_exit_handler(
761     std::function<void(Environment*, int)>&& handler) {
762   process_exit_handler_ = std::move(handler);
763 }
764 
765 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
766 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
767 #define VS(PropertyName, StringValue) V(v8::String, PropertyName)
768 #define V(TypeName, PropertyName)                                             \
769   inline                                                                      \
770   v8::Local<TypeName> IsolateData::PropertyName() const {                     \
771     return PropertyName ## _ .Get(isolate_);                                  \
772   }
773   PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
PER_ISOLATE_SYMBOL_PROPERTIES(VY)774   PER_ISOLATE_SYMBOL_PROPERTIES(VY)
775   PER_ISOLATE_STRING_PROPERTIES(VS)
776 #undef V
777 #undef VS
778 #undef VY
779 #undef VP
780 
781 #define V(PropertyName, TypeName)                                              \
782   inline v8::Local<TypeName> IsolateData::PropertyName() const {               \
783     return PropertyName##_.Get(isolate_);                                      \
784   }                                                                            \
785   inline void IsolateData::set_##PropertyName(v8::Local<TypeName> value) {     \
786     PropertyName##_.Set(isolate_, value);                                      \
787   }
788   PER_ISOLATE_TEMPLATE_PROPERTIES(V)
789 #undef V
790 
791 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
792 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
793 #define VS(PropertyName, StringValue) V(v8::String, PropertyName)
794 #define V(TypeName, PropertyName)                                             \
795   inline v8::Local<TypeName> Environment::PropertyName() const {              \
796     return isolate_data()->PropertyName();                                    \
797   }
798   PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
799   PER_ISOLATE_SYMBOL_PROPERTIES(VY)
800   PER_ISOLATE_STRING_PROPERTIES(VS)
801 #undef V
802 #undef VS
803 #undef VY
804 #undef VP
805 
806 #define V(PropertyName, TypeName)                                              \
807   inline v8::Local<TypeName> Environment::PropertyName() const {               \
808     return isolate_data()->PropertyName();                                     \
809   }                                                                            \
810   inline void Environment::set_##PropertyName(v8::Local<TypeName> value) {     \
811     DCHECK(isolate_data()->PropertyName().IsEmpty());                          \
812     isolate_data()->set_##PropertyName(value);                                 \
813   }
814   PER_ISOLATE_TEMPLATE_PROPERTIES(V)
815 #undef V
816 
817 #define V(PropertyName, TypeName)                                              \
818   inline v8::Local<TypeName> Environment::PropertyName() const {               \
819     DCHECK_NOT_NULL(principal_realm_);                                         \
820     return principal_realm_->PropertyName();                                   \
821   }                                                                            \
822   inline void Environment::set_##PropertyName(v8::Local<TypeName> value) {     \
823     DCHECK_NOT_NULL(principal_realm_);                                         \
824     principal_realm_->set_##PropertyName(value);                               \
825   }
826   PER_REALM_STRONG_PERSISTENT_VALUES(V)
827 #undef V
828 
829 v8::Local<v8::Context> Environment::context() const {
830   return principal_realm()->context();
831 }
832 
principal_realm()833 Realm* Environment::principal_realm() const {
834   return principal_realm_.get();
835 }
836 
set_heap_snapshot_near_heap_limit(uint32_t limit)837 inline void Environment::set_heap_snapshot_near_heap_limit(uint32_t limit) {
838   heap_snapshot_near_heap_limit_ = limit;
839 }
840 
is_in_heapsnapshot_heap_limit_callback()841 inline bool Environment::is_in_heapsnapshot_heap_limit_callback() const {
842   return is_in_heapsnapshot_heap_limit_callback_;
843 }
844 
AddHeapSnapshotNearHeapLimitCallback()845 inline void Environment::AddHeapSnapshotNearHeapLimitCallback() {
846   DCHECK(!heapsnapshot_near_heap_limit_callback_added_);
847   heapsnapshot_near_heap_limit_callback_added_ = true;
848   isolate_->AddNearHeapLimitCallback(Environment::NearHeapLimitCallback, this);
849 }
850 
RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit)851 inline void Environment::RemoveHeapSnapshotNearHeapLimitCallback(
852     size_t heap_limit) {
853   DCHECK(heapsnapshot_near_heap_limit_callback_added_);
854   heapsnapshot_near_heap_limit_callback_added_ = false;
855   isolate_->RemoveNearHeapLimitCallback(Environment::NearHeapLimitCallback,
856                                         heap_limit);
857 }
858 
859 }  // namespace node
860 
861 // These two files depend on each other. Including base_object-inl.h after this
862 // file is the easiest way to avoid issues with that circular dependency.
863 #include "base_object-inl.h"
864 
865 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
866 
867 #endif  // SRC_ENV_INL_H_
868