• 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-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