22 #ifndef SRC_ENV_INL_H_ 23 #define SRC_ENV_INL_H_ 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 39 inline IsolateData::IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop,
40 uint32_t* zero_fill_field) :
51 #define
V(PropertyName, StringValue) \
56 v8::String::NewFromOneByte( \
58 reinterpret_cast<const uint8_t*>(StringValue), \
59 v8::NewStringType::kInternalized, \
60 sizeof(StringValue) - 1).ToLocalChecked())),
61 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(
V)
63 #define
V(PropertyName, StringValue) \
66 v8::String::NewFromOneByte( \
68 reinterpret_cast<const uint8_t*>(StringValue), \
69 v8::NewStringType::kInternalized, \
70 sizeof(StringValue) - 1).ToLocalChecked()),
71 PER_ISOLATE_STRING_PROPERTIES(
V)
73 event_loop_(event_loop), zero_fill_field_(zero_fill_field) {}
75 inline uv_loop_t* IsolateData::event_loop()
const {
79 inline uint32_t* IsolateData::zero_fill_field()
const {
80 return zero_fill_field_;
87 v8::HandleScope handle_scope(isolate_);
91 uid_fields_[AsyncHooks::kAsyncUidCntr] = 1;
97 providers_[AsyncWrap::PROVIDER_ ## Provider].Set( \ 99 v8::String::NewFromOneByte( \ 101 reinterpret_cast<const uint8_t*>(#Provider), \ 102 v8::NewStringType::kInternalized, \ 103 sizeof(#Provider) - 1).ToLocalChecked()); 104 NODE_ASYNC_PROVIDER_TYPES(
V)
108 inline uint32_t* Environment::AsyncHooks::fields() {
112 inline int Environment::AsyncHooks::fields_count()
const {
116 inline double* Environment::AsyncHooks::uid_fields() {
120 inline int Environment::AsyncHooks::uid_fields_count()
const {
121 return kUidFieldsCount;
124 inline v8::Local<v8::String> Environment::AsyncHooks::provider_string(
int idx) {
125 return providers_[idx].Get(isolate_);
128 inline void Environment::AsyncHooks::push_ids(
double async_id,
130 CHECK_GE(async_id, -1);
131 CHECK_GE(trigger_id, -1);
133 ids_stack_.push({ uid_fields_[kCurrentAsyncId],
134 uid_fields_[kCurrentTriggerId] });
135 uid_fields_[kCurrentAsyncId] =
async_id;
136 uid_fields_[kCurrentTriggerId] = trigger_id;
139 inline bool Environment::AsyncHooks::pop_ids(
double async_id) {
142 if (ids_stack_.empty())
return false;
146 if (uid_fields_[kCurrentAsyncId] != async_id) {
148 "Error: async hook stack has become corrupted (" 149 "actual: %.f, expected: %.f)\n",
150 uid_fields_[kCurrentAsyncId],
152 Environment* env = Environment::GetCurrent(isolate_);
155 if (!env->abort_on_uncaught_exception())
157 fprintf(stderr,
"\n");
159 ABORT_NO_BACKTRACE();
162 auto ids = ids_stack_.top();
164 uid_fields_[kCurrentAsyncId] = ids.async_id;
165 uid_fields_[kCurrentTriggerId] = ids.trigger_id;
166 return !ids_stack_.empty();
169 inline size_t Environment::AsyncHooks::stack_size() {
170 return ids_stack_.size();
173 inline void Environment::AsyncHooks::clear_id_stack() {
174 while (!ids_stack_.empty())
176 uid_fields_[kCurrentAsyncId] = 0;
177 uid_fields_[kCurrentTriggerId] = 0;
180 inline Environment::AsyncHooks::InitScope::InitScope(
181 Environment* env,
double init_trigger_id)
183 uid_fields_ref_(env->async_hooks()->uid_fields()) {
184 CHECK_GE(init_trigger_id, -1);
185 env->async_hooks()->push_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId],
189 inline Environment::AsyncHooks::InitScope::~InitScope() {
190 env_->async_hooks()->pop_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId]);
193 inline Environment::AsyncHooks::ExecScope::ExecScope(
194 Environment* env,
double async_id,
double trigger_id)
198 CHECK_GE(async_id, -1);
199 CHECK_GE(trigger_id, -1);
200 env->async_hooks()->push_ids(async_id, trigger_id);
203 inline Environment::AsyncHooks::ExecScope::~ExecScope() {
204 if (disposed_)
return;
208 inline void Environment::AsyncHooks::ExecScope::Dispose() {
210 env_->async_hooks()->pop_ids(async_id_);
213 inline Environment::AsyncCallbackScope::AsyncCallbackScope(Environment* env)
215 env_->makecallback_cntr_++;
218 inline Environment::AsyncCallbackScope::~AsyncCallbackScope() {
219 env_->makecallback_cntr_--;
222 inline bool Environment::AsyncCallbackScope::in_makecallback() {
223 return env_->makecallback_cntr_ > 1;
226 inline Environment::DomainFlag::DomainFlag() {
227 for (
int i = 0; i < kFieldsCount; ++i)
fields_[i] = 0;
230 inline uint32_t* Environment::DomainFlag::fields() {
234 inline int Environment::DomainFlag::fields_count()
const {
238 inline uint32_t Environment::DomainFlag::count()
const {
242 inline Environment::TickInfo::TickInfo() {
243 for (
int i = 0; i < kFieldsCount; ++i)
247 inline uint32_t* Environment::TickInfo::fields() {
251 inline int Environment::TickInfo::fields_count()
const {
255 inline uint32_t Environment::TickInfo::index()
const {
259 inline uint32_t Environment::TickInfo::length()
const {
263 inline void Environment::TickInfo::set_index(uint32_t value) {
267 inline void Environment::AssignToContext(v8::Local<v8::Context> context) {
268 context->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex,
this);
270 inspector_agent()->ContextCreated(context);
271 #endif // HAVE_INSPECTOR 274 inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
275 return GetCurrent(isolate->GetCurrentContext());
278 inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
279 return static_cast<Environment*
>(
280 context->GetAlignedPointerFromEmbedderData(kContextEmbedderDataIndex));
283 inline Environment* Environment::GetCurrent(
284 const v8::FunctionCallbackInfo<v8::Value>& info) {
285 CHECK(info.Data()->IsExternal());
286 return static_cast<Environment*
>(info.Data().As<v8::External>()->Value());
289 template <
typename T>
290 inline Environment* Environment::GetCurrent(
291 const v8::PropertyCallbackInfo<T>& info) {
292 CHECK(info.Data()->IsExternal());
293 return static_cast<Environment*
>(
294 info.Data().template As<v8::External>()->Value());
297 inline Environment::Environment(IsolateData* isolate_data,
298 v8::Local<v8::Context> context)
299 : isolate_(context->GetIsolate()),
300 isolate_data_(isolate_data),
301 async_hooks_(context->GetIsolate()),
302 timer_base_(uv_now(isolate_data->event_loop())),
303 using_domains_(false),
304 printed_error_(false),
305 trace_sync_io_(false),
306 abort_on_uncaught_exception_(false),
307 makecallback_cntr_(0),
309 inspector_agent_(this),
311 handle_cleanup_waiting_(0),
313 fs_stats_field_array_(
nullptr),
314 context_(context->GetIsolate(), context) {
316 v8::HandleScope handle_scope(isolate());
317 v8::Context::Scope context_scope(context);
322 AssignToContext(context);
324 destroy_ids_list_.reserve(512);
325 performance_state_ = Calloc<performance::performance_state>(1);
326 performance_state_->milestones[
327 performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT] =
329 performance_state_->milestones[
330 performance::NODE_PERFORMANCE_MILESTONE_NODE_START] =
332 performance_state_->milestones[
333 performance::NODE_PERFORMANCE_MILESTONE_V8_START] =
337 inline Environment::~Environment() {
338 v8::HandleScope handle_scope(isolate());
340 context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex,
342 #define V(PropertyName, TypeName) PropertyName ## _.Reset(); 343 ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(
V)
346 delete[] heap_statistics_buffer_;
347 delete[] heap_space_statistics_buffer_;
348 delete[] http_parser_buffer_;
349 free(http2_state_buffer_);
350 free(performance_state_);
353 inline v8::Isolate* Environment::isolate()
const {
357 inline bool Environment::in_domain()
const {
359 return using_domains() &&
360 const_cast<Environment*
>(
this)->domain_flag()->count() > 0;
363 inline Environment* Environment::from_immediate_check_handle(
364 uv_check_t* handle) {
365 return ContainerOf(&Environment::immediate_check_handle_, handle);
368 inline uv_check_t* Environment::immediate_check_handle() {
369 return &immediate_check_handle_;
372 inline uv_idle_t* Environment::immediate_idle_handle() {
373 return &immediate_idle_handle_;
376 inline Environment* Environment::from_destroy_ids_timer_handle(
377 uv_timer_t* handle) {
378 return ContainerOf(&Environment::destroy_ids_timer_handle_, handle);
381 inline uv_timer_t* Environment::destroy_ids_timer_handle() {
382 return &destroy_ids_timer_handle_;
385 inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
388 handle_cleanup_queue_.PushBack(
new HandleCleanup(handle, cb, arg));
391 inline void Environment::FinishHandleCleanup(uv_handle_t* handle) {
392 handle_cleanup_waiting_--;
395 inline uv_loop_t* Environment::event_loop()
const {
396 return isolate_data()->event_loop();
400 return &async_hooks_;
403 inline Environment::DomainFlag* Environment::domain_flag() {
404 return &domain_flag_;
407 inline Environment::TickInfo* Environment::tick_info() {
411 inline uint64_t Environment::timer_base()
const {
415 inline bool Environment::using_domains()
const {
416 return using_domains_;
419 inline void Environment::set_using_domains(
bool value) {
420 using_domains_ = value;
423 inline bool Environment::printed_error()
const {
424 return printed_error_;
427 inline void Environment::set_printed_error(
bool value) {
428 printed_error_ = value;
431 inline void Environment::set_trace_sync_io(
bool value) {
432 trace_sync_io_ = value;
435 inline bool Environment::abort_on_uncaught_exception()
const {
436 return abort_on_uncaught_exception_;
439 inline void Environment::set_abort_on_uncaught_exception(
bool value) {
440 abort_on_uncaught_exception_ = value;
443 inline std::vector<double>* Environment::destroy_ids_list() {
444 return &destroy_ids_list_;
447 inline double Environment::new_async_id() {
448 return ++async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr];
451 inline double Environment::current_async_id() {
452 return async_hooks()->uid_fields()[AsyncHooks::kCurrentAsyncId];
455 inline double Environment::trigger_id() {
456 return async_hooks()->uid_fields()[AsyncHooks::kCurrentTriggerId];
459 inline double Environment::get_init_trigger_id() {
460 double* uid_fields = async_hooks()->uid_fields();
461 double tid = uid_fields[AsyncHooks::kInitTriggerId];
462 uid_fields[AsyncHooks::kInitTriggerId] = 0;
463 if (tid <= 0) tid = current_async_id();
467 inline void Environment::set_init_trigger_id(
const double id) {
468 async_hooks()->uid_fields()[AsyncHooks::kInitTriggerId] = id;
471 inline double* Environment::heap_statistics_buffer()
const {
472 CHECK_NE(heap_statistics_buffer_,
nullptr);
473 return heap_statistics_buffer_;
476 inline void Environment::set_heap_statistics_buffer(
double* pointer) {
477 CHECK_EQ(heap_statistics_buffer_,
nullptr);
478 heap_statistics_buffer_ = pointer;
481 inline double* Environment::heap_space_statistics_buffer()
const {
482 CHECK_NE(heap_space_statistics_buffer_,
nullptr);
483 return heap_space_statistics_buffer_;
486 inline void Environment::set_heap_space_statistics_buffer(
double* pointer) {
487 CHECK_EQ(heap_space_statistics_buffer_,
nullptr);
488 heap_space_statistics_buffer_ = pointer;
491 inline char* Environment::http_parser_buffer()
const {
492 return http_parser_buffer_;
495 inline void Environment::set_http_parser_buffer(
char* buffer) {
496 CHECK_EQ(http_parser_buffer_,
nullptr);
497 http_parser_buffer_ = buffer;
500 inline http2::http2_state* Environment::http2_state_buffer()
const {
501 return http2_state_buffer_;
504 inline void Environment::set_http2_state_buffer(http2::http2_state* buffer) {
505 CHECK_EQ(http2_state_buffer_,
nullptr);
506 http2_state_buffer_ = buffer;
509 inline double* Environment::fs_stats_field_array()
const {
510 return fs_stats_field_array_;
513 inline void Environment::set_fs_stats_field_array(
double* fields) {
514 CHECK_EQ(fs_stats_field_array_,
nullptr);
515 fs_stats_field_array_ = fields;
518 inline performance::performance_state* Environment::performance_state() {
519 return performance_state_;
522 inline std::map<std::string, uint64_t>* Environment::performance_marks() {
523 return &performance_marks_;
526 inline Environment* Environment::from_performance_check_handle(
527 uv_check_t* handle) {
528 return ContainerOf(&Environment::performance_check_handle_, handle);
531 inline Environment* Environment::from_performance_idle_handle(
533 return ContainerOf(&Environment::performance_idle_handle_, handle);
536 inline Environment* Environment::from_performance_prepare_handle(
537 uv_prepare_t* handle) {
538 return ContainerOf(&Environment::performance_prepare_handle_, handle);
541 inline uv_check_t* Environment::performance_check_handle() {
542 return &performance_check_handle_;
545 inline uv_idle_t* Environment::performance_idle_handle() {
546 return &performance_idle_handle_;
549 inline uv_prepare_t* Environment::performance_prepare_handle() {
550 return &performance_prepare_handle_;
553 inline IsolateData* Environment::isolate_data()
const {
554 return isolate_data_;
557 inline void Environment::ThrowError(
const char* errmsg) {
558 ThrowError(v8::Exception::Error, errmsg);
561 inline void Environment::ThrowTypeError(
const char* errmsg) {
562 ThrowError(v8::Exception::TypeError, errmsg);
565 inline void Environment::ThrowRangeError(
const char* errmsg) {
566 ThrowError(v8::Exception::RangeError, errmsg);
569 inline void Environment::ThrowError(
570 v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
571 const char* errmsg) {
572 v8::HandleScope handle_scope(isolate());
573 isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
576 inline void Environment::ThrowErrnoException(
int errorno,
580 isolate()->ThrowException(
584 inline void Environment::ThrowUVException(
int errorno,
589 isolate()->ThrowException(
590 UVException(isolate(), errorno, syscall, message, path, dest));
593 inline v8::Local<v8::FunctionTemplate>
594 Environment::NewFunctionTemplate(v8::FunctionCallback callback,
595 v8::Local<v8::Signature> signature) {
596 v8::Local<v8::External> external = as_external();
600 inline void Environment::SetMethod(v8::Local<v8::Object> that,
602 v8::FunctionCallback callback) {
603 v8::Local<v8::Function>
function =
604 NewFunctionTemplate(callback)->GetFunction();
606 const v8::NewStringType type = v8::NewStringType::kInternalized;
607 v8::Local<v8::String> name_string =
608 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
609 that->Set(name_string,
function);
610 function->SetName(name_string);
613 inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
615 v8::FunctionCallback callback) {
617 v8::Local<v8::FunctionTemplate>
t = NewFunctionTemplate(callback, signature);
619 const v8::NewStringType type = v8::NewStringType::kInternalized;
620 v8::Local<v8::String> name_string =
621 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
622 that->PrototypeTemplate()->Set(name_string, t);
623 t->SetClassName(name_string);
626 inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
628 v8::FunctionCallback callback) {
629 v8::Local<v8::FunctionTemplate> t = NewFunctionTemplate(callback);
631 const v8::NewStringType type = v8::NewStringType::kInternalized;
632 v8::Local<v8::String> name_string =
633 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
634 that->Set(name_string, t);
635 t->SetClassName(name_string);
638 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 639 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 640 #define V(TypeName, PropertyName) \ 642 v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \ 644 return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate); \ 646 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
647 PER_ISOLATE_STRING_PROPERTIES(VS)
652 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 653 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 654 #define V(TypeName, PropertyName) \ 655 inline v8::Local<TypeName> Environment::PropertyName() const { \ 656 return isolate_data()->PropertyName(isolate()); \ 658 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
659 PER_ISOLATE_STRING_PROPERTIES(VS)
664 #define V(PropertyName, TypeName) \ 665 inline v8::Local<TypeName> Environment::PropertyName() const { \ 666 return StrongPersistentToLocal(PropertyName ## _); \ 668 inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \ 669 PropertyName ## _.Reset(isolate(), value); \ 671 ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(
V)
676 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 678 #endif // SRC_ENV_INL_H_
#define PERFORMANCE_NOW()
Persistent< Context > context_
Local< Value > ErrnoException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path)
void DumpBacktrace(FILE *fp)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
node::Environment::AsyncHooks AsyncHooks
Local< Value > UVException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path)