The C and C++ Include Header Files
/usr/include/nodejs/src/env-inl.h
$ cat -n /usr/include/nodejs/src/env-inl.h 1 // Copyright Joyent, Inc. and other Node contributors. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a 4 // copy of this software and associated documentation files (the 5 // "Software"), to deal in the Software without restriction, including 6 // without limitation the rights to use, copy, modify, merge, publish, 7 // distribute, sublicense, and/or sell copies of the Software, and to permit 8 // persons to whom the Software is furnished to do so, subject to the 9 // following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included 12 // in all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 #ifndef SRC_ENV_INL_H_ 23 #define SRC_ENV_INL_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "aliased_buffer.h" 28 #include "callback_queue-inl.h" 29 #include "env.h" 30 #include "node.h" 31 #include "util-inl.h" 32 #include "uv.h" 33 #include "v8.h" 34 #include "node_perf_common.h" 35 #include "node_context_data.h" 36 37 #include
38 #include
39 40 #include
41 42 namespace node { 43 44 inline v8::Isolate* IsolateData::isolate() const { 45 return isolate_; 46 } 47 48 inline uv_loop_t* IsolateData::event_loop() const { 49 return event_loop_; 50 } 51 52 inline bool IsolateData::uses_node_allocator() const { 53 return uses_node_allocator_; 54 } 55 56 inline v8::ArrayBuffer::Allocator* IsolateData::allocator() const { 57 return allocator_; 58 } 59 60 inline NodeArrayBufferAllocator* IsolateData::node_allocator() const { 61 return node_allocator_; 62 } 63 64 inline MultiIsolatePlatform* IsolateData::platform() const { 65 return platform_; 66 } 67 68 inline v8::Local
IsolateData::async_wrap_provider(int index) const { 69 return async_wrap_providers_[index].Get(isolate_); 70 } 71 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 77 inline worker::Worker* IsolateData::worker_context() const { 78 return worker_context_; 79 } 80 81 inline AsyncHooks::AsyncHooks() 82 : async_ids_stack_(env()->isolate(), 16 * 2), 83 fields_(env()->isolate(), kFieldsCount), 84 async_id_fields_(env()->isolate(), kUidFieldsCount) { 85 clear_async_id_stack(); 86 87 // Always perform async_hooks checks, not just when async_hooks is enabled. 88 // TODO(AndreasMadsen): Consider removing this for LTS releases. 89 // See discussion in https://github.com/nodejs/node/pull/15454 90 // When removing this, do it by reverting the commit. Otherwise the test 91 // and flag changes won't be included. 92 fields_[kCheck] = 1; 93 94 // kDefaultTriggerAsyncId should be -1, this indicates that there is no 95 // specified default value and it should fallback to the executionAsyncId. 96 // 0 is not used as the magic value, because that indicates a missing context 97 // which is different from a default context. 98 async_id_fields_[AsyncHooks::kDefaultTriggerAsyncId] = -1; 99 100 // kAsyncIdCounter should start at 1 because that'll be the id the execution 101 // context during bootstrap (code that runs before entering uv_run()). 102 async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1; 103 } 104 inline AliasedUint32Array& AsyncHooks::fields() { 105 return fields_; 106 } 107 108 inline AliasedFloat64Array& AsyncHooks::async_id_fields() { 109 return async_id_fields_; 110 } 111 112 inline AliasedFloat64Array& AsyncHooks::async_ids_stack() { 113 return async_ids_stack_; 114 } 115 116 v8::Local
AsyncHooks::js_execution_async_resources() { 117 if (UNLIKELY(js_execution_async_resources_.IsEmpty())) { 118 js_execution_async_resources_.Reset( 119 env()->isolate(), v8::Array::New(env()->isolate())); 120 } 121 return PersistentToLocal::Strong(js_execution_async_resources_); 122 } 123 124 v8::Local
AsyncHooks::native_execution_async_resource(size_t i) { 125 if (i >= native_execution_async_resources_.size()) return {}; 126 return PersistentToLocal::Strong(native_execution_async_resources_[i]); 127 } 128 129 inline v8::Local
AsyncHooks::provider_string(int idx) { 130 return env()->isolate_data()->async_wrap_provider(idx); 131 } 132 133 inline void AsyncHooks::no_force_checks() { 134 fields_[kCheck] -= 1; 135 } 136 137 inline Environment* AsyncHooks::env() { 138 return Environment::ForAsyncHooks(this); 139 } 140 141 // Remember to keep this code aligned with pushAsyncContext() in JS. 142 inline void AsyncHooks::push_async_context(double async_id, 143 double trigger_async_id, 144 v8::Local
resource) { 145 // Since async_hooks is experimental, do only perform the check 146 // when async_hooks is enabled. 147 if (fields_[kCheck] > 0) { 148 CHECK_GE(async_id, -1); 149 CHECK_GE(trigger_async_id, -1); 150 } 151 152 uint32_t offset = fields_[kStackLength]; 153 if (offset * 2 >= async_ids_stack_.Length()) 154 grow_async_ids_stack(); 155 async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId]; 156 async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId]; 157 fields_[kStackLength] += 1; 158 async_id_fields_[kExecutionAsyncId] = async_id; 159 async_id_fields_[kTriggerAsyncId] = trigger_async_id; 160 161 #ifdef DEBUG 162 for (uint32_t i = offset; i < native_execution_async_resources_.size(); i++) 163 CHECK(native_execution_async_resources_[i].IsEmpty()); 164 #endif 165 166 // When this call comes from JS (as a way of increasing the stack size), 167 // `resource` will be empty, because JS caches these values anyway, and 168 // we should avoid creating strong global references that might keep 169 // these JS resource objects alive longer than necessary. 170 if (!resource.IsEmpty()) { 171 native_execution_async_resources_.resize(offset + 1); 172 native_execution_async_resources_[offset].Reset(env()->isolate(), resource); 173 } 174 } 175 176 // Remember to keep this code aligned with popAsyncContext() in JS. 177 inline bool AsyncHooks::pop_async_context(double async_id) { 178 // In case of an exception then this may have already been reset, if the 179 // stack was multiple MakeCallback()'s deep. 180 if (fields_[kStackLength] == 0) return false; 181 182 // Ask for the async_id to be restored as a check that the stack 183 // hasn't been corrupted. 184 // Since async_hooks is experimental, do only perform the check 185 // when async_hooks is enabled. 186 if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) { 187 fprintf(stderr, 188 "Error: async hook stack has become corrupted (" 189 "actual: %.f, expected: %.f)\n", 190 async_id_fields_.GetValue(kExecutionAsyncId), 191 async_id); 192 DumpBacktrace(stderr); 193 fflush(stderr); 194 if (!env()->abort_on_uncaught_exception()) 195 exit(1); 196 fprintf(stderr, "\n"); 197 fflush(stderr); 198 ABORT_NO_BACKTRACE(); 199 } 200 201 uint32_t offset = fields_[kStackLength] - 1; 202 async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset]; 203 async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1]; 204 fields_[kStackLength] = offset; 205 206 if (LIKELY(offset < native_execution_async_resources_.size() && 207 !native_execution_async_resources_[offset].IsEmpty())) { 208 #ifdef DEBUG 209 for (uint32_t i = offset + 1; 210 i < native_execution_async_resources_.size(); 211 i++) { 212 CHECK(native_execution_async_resources_[i].IsEmpty()); 213 } 214 #endif 215 native_execution_async_resources_.resize(offset); 216 if (native_execution_async_resources_.size() < 217 native_execution_async_resources_.capacity() / 2 && 218 native_execution_async_resources_.size() > 16) { 219 native_execution_async_resources_.shrink_to_fit(); 220 } 221 } 222 223 if (UNLIKELY(js_execution_async_resources()->Length() > offset)) { 224 v8::HandleScope handle_scope(env()->isolate()); 225 USE(js_execution_async_resources()->Set( 226 env()->context(), 227 env()->length_string(), 228 v8::Integer::NewFromUnsigned(env()->isolate(), offset))); 229 } 230 231 return fields_[kStackLength] > 0; 232 } 233 234 void AsyncHooks::clear_async_id_stack() { 235 v8::Isolate* isolate = env()->isolate(); 236 v8::HandleScope handle_scope(isolate); 237 if (!js_execution_async_resources_.IsEmpty()) { 238 USE(PersistentToLocal::Strong(js_execution_async_resources_)->Set( 239 env()->context(), 240 env()->length_string(), 241 v8::Integer::NewFromUnsigned(isolate, 0))); 242 } 243 native_execution_async_resources_.clear(); 244 native_execution_async_resources_.shrink_to_fit(); 245 246 async_id_fields_[kExecutionAsyncId] = 0; 247 async_id_fields_[kTriggerAsyncId] = 0; 248 fields_[kStackLength] = 0; 249 } 250 251 // The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in 252 // async_wrap-inl.h to avoid a circular dependency. 253 254 inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope( 255 Environment* env, double default_trigger_async_id) 256 : async_hooks_(env->async_hooks()) { 257 if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) { 258 CHECK_GE(default_trigger_async_id, 0); 259 } 260 261 old_default_trigger_async_id_ = 262 async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; 263 async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = 264 default_trigger_async_id; 265 } 266 267 inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() { 268 async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = 269 old_default_trigger_async_id_; 270 } 271 272 Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) { 273 return ContainerOf(&Environment::async_hooks_, hooks); 274 } 275 276 inline size_t Environment::async_callback_scope_depth() const { 277 return async_callback_scope_depth_; 278 } 279 280 inline void Environment::PushAsyncCallbackScope() { 281 async_callback_scope_depth_++; 282 } 283 284 inline void Environment::PopAsyncCallbackScope() { 285 async_callback_scope_depth_--; 286 } 287 288 inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate) 289 : fields_(isolate, kFieldsCount) {} 290 291 inline AliasedUint32Array& ImmediateInfo::fields() { 292 return fields_; 293 } 294 295 inline uint32_t ImmediateInfo::count() const { 296 return fields_[kCount]; 297 } 298 299 inline uint32_t ImmediateInfo::ref_count() const { 300 return fields_[kRefCount]; 301 } 302 303 inline bool ImmediateInfo::has_outstanding() const { 304 return fields_[kHasOutstanding] == 1; 305 } 306 307 inline void ImmediateInfo::ref_count_inc(uint32_t increment) { 308 fields_[kRefCount] += increment; 309 } 310 311 inline void ImmediateInfo::ref_count_dec(uint32_t decrement) { 312 fields_[kRefCount] -= decrement; 313 } 314 315 inline TickInfo::TickInfo(v8::Isolate* isolate) 316 : fields_(isolate, kFieldsCount) {} 317 318 inline AliasedUint8Array& TickInfo::fields() { 319 return fields_; 320 } 321 322 inline bool TickInfo::has_tick_scheduled() const { 323 return fields_[kHasTickScheduled] == 1; 324 } 325 326 inline bool TickInfo::has_rejection_to_warn() const { 327 return fields_[kHasRejectionToWarn] == 1; 328 } 329 330 inline void Environment::AssignToContext(v8::Local
context, 331 const ContextInfo& info) { 332 context->SetAlignedPointerInEmbedderData( 333 ContextEmbedderIndex::kEnvironment, this); 334 // Used by Environment::GetCurrent to know that we are on a node context. 335 context->SetAlignedPointerInEmbedderData( 336 ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr); 337 #if HAVE_INSPECTOR 338 inspector_agent()->ContextCreated(context, info); 339 #endif // HAVE_INSPECTOR 340 } 341 342 inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { 343 if (UNLIKELY(!isolate->InContext())) return nullptr; 344 v8::HandleScope handle_scope(isolate); 345 return GetCurrent(isolate->GetCurrentContext()); 346 } 347 348 inline Environment* Environment::GetCurrent(v8::Local
context) { 349 if (UNLIKELY(context.IsEmpty())) { 350 return nullptr; 351 } 352 if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <= 353 ContextEmbedderIndex::kContextTag)) { 354 return nullptr; 355 } 356 if (UNLIKELY(context->GetAlignedPointerFromEmbedderData( 357 ContextEmbedderIndex::kContextTag) != 358 Environment::kNodeContextTagPtr)) { 359 return nullptr; 360 } 361 return static_cast
( 362 context->GetAlignedPointerFromEmbedderData( 363 ContextEmbedderIndex::kEnvironment)); 364 } 365 366 inline Environment* Environment::GetCurrent( 367 const v8::FunctionCallbackInfo
& info) { 368 return GetFromCallbackData(info.Data()); 369 } 370 371 template
372 inline Environment* Environment::GetCurrent( 373 const v8::PropertyCallbackInfo
& info) { 374 return GetFromCallbackData(info.Data()); 375 } 376 377 inline Environment* Environment::GetFromCallbackData(v8::Local
val) { 378 DCHECK(val->IsObject()); 379 v8::Local
obj = val.As
(); 380 DCHECK_GE(obj->InternalFieldCount(), 1); 381 Environment* env = 382 static_cast
(obj->GetAlignedPointerFromInternalField(0)); 383 DCHECK(env->as_callback_data_template()->HasInstance(obj)); 384 return env; 385 } 386 387 inline Environment* Environment::GetThreadLocalEnv() { 388 return static_cast
(uv_key_get(&thread_local_env)); 389 } 390 391 inline bool Environment::profiler_idle_notifier_started() const { 392 return profiler_idle_notifier_started_; 393 } 394 395 inline v8::Isolate* Environment::isolate() const { 396 return isolate_; 397 } 398 399 inline Environment* Environment::from_timer_handle(uv_timer_t* handle) { 400 return ContainerOf(&Environment::timer_handle_, handle); 401 } 402 403 inline uv_timer_t* Environment::timer_handle() { 404 return &timer_handle_; 405 } 406 407 inline Environment* Environment::from_immediate_check_handle( 408 uv_check_t* handle) { 409 return ContainerOf(&Environment::immediate_check_handle_, handle); 410 } 411 412 inline uv_check_t* Environment::immediate_check_handle() { 413 return &immediate_check_handle_; 414 } 415 416 inline uv_idle_t* Environment::immediate_idle_handle() { 417 return &immediate_idle_handle_; 418 } 419 420 inline void Environment::RegisterHandleCleanup(uv_handle_t* handle, 421 HandleCleanupCb cb, 422 void* arg) { 423 handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg}); 424 } 425 426 template
427 inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) { 428 handle_cleanup_waiting_++; 429 static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle"); 430 static_assert(offsetof(T, data) == offsetof(uv_handle_t, data), 431 "T is a libuv handle"); 432 static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb), 433 "T is a libuv handle"); 434 struct CloseData { 435 Environment* env; 436 OnCloseCallback callback; 437 void* original_data; 438 }; 439 handle->data = new CloseData { this, callback, handle->data }; 440 uv_close(reinterpret_cast
(handle), [](uv_handle_t* handle) { 441 std::unique_ptr
data { static_cast
(handle->data) }; 442 data->env->handle_cleanup_waiting_--; 443 handle->data = data->original_data; 444 data->callback(reinterpret_cast
(handle)); 445 }); 446 } 447 448 void Environment::IncreaseWaitingRequestCounter() { 449 request_waiting_++; 450 } 451 452 void Environment::DecreaseWaitingRequestCounter() { 453 request_waiting_--; 454 CHECK_GE(request_waiting_, 0); 455 } 456 457 inline uv_loop_t* Environment::event_loop() const { 458 return isolate_data()->event_loop(); 459 } 460 461 inline void Environment::TryLoadAddon( 462 const char* filename, 463 int flags, 464 const std::function
& was_loaded) { 465 loaded_addons_.emplace_back(filename, flags); 466 if (!was_loaded(&loaded_addons_.back())) { 467 loaded_addons_.pop_back(); 468 } 469 } 470 471 #if HAVE_INSPECTOR 472 inline bool Environment::is_in_inspector_console_call() const { 473 return is_in_inspector_console_call_; 474 } 475 476 inline void Environment::set_is_in_inspector_console_call(bool value) { 477 is_in_inspector_console_call_ = value; 478 } 479 #endif 480 481 inline AsyncHooks* Environment::async_hooks() { 482 return &async_hooks_; 483 } 484 485 inline ImmediateInfo* Environment::immediate_info() { 486 return &immediate_info_; 487 } 488 489 inline TickInfo* Environment::tick_info() { 490 return &tick_info_; 491 } 492 493 inline uint64_t Environment::timer_base() const { 494 return timer_base_; 495 } 496 497 inline std::shared_ptr
Environment::env_vars() { 498 return env_vars_; 499 } 500 501 inline void Environment::set_env_vars(std::shared_ptr
env_vars) { 502 env_vars_ = env_vars; 503 } 504 505 inline bool Environment::printed_error() const { 506 return printed_error_; 507 } 508 509 inline void Environment::set_printed_error(bool value) { 510 printed_error_ = value; 511 } 512 513 inline void Environment::set_trace_sync_io(bool value) { 514 trace_sync_io_ = value; 515 } 516 517 inline bool Environment::abort_on_uncaught_exception() const { 518 return options_->abort_on_uncaught_exception; 519 } 520 521 inline void Environment::set_force_context_aware(bool value) { 522 options_->force_context_aware = value; 523 } 524 525 inline bool Environment::force_context_aware() const { 526 return options_->force_context_aware; 527 } 528 529 inline void Environment::set_abort_on_uncaught_exception(bool value) { 530 options_->abort_on_uncaught_exception = value; 531 } 532 533 inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() { 534 return should_abort_on_uncaught_toggle_; 535 } 536 537 inline AliasedInt32Array& Environment::stream_base_state() { 538 return stream_base_state_; 539 } 540 541 inline uint32_t Environment::get_next_module_id() { 542 return module_id_counter_++; 543 } 544 inline uint32_t Environment::get_next_script_id() { 545 return script_id_counter_++; 546 } 547 inline uint32_t Environment::get_next_function_id() { 548 return function_id_counter_++; 549 } 550 551 ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope( 552 Environment* env) 553 : env_(env) { 554 env_->PushShouldNotAbortOnUncaughtScope(); 555 } 556 557 ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() { 558 Close(); 559 } 560 561 void ShouldNotAbortOnUncaughtScope::Close() { 562 if (env_ != nullptr) { 563 env_->PopShouldNotAbortOnUncaughtScope(); 564 env_ = nullptr; 565 } 566 } 567 568 inline void Environment::PushShouldNotAbortOnUncaughtScope() { 569 should_not_abort_scope_counter_++; 570 } 571 572 inline void Environment::PopShouldNotAbortOnUncaughtScope() { 573 should_not_abort_scope_counter_--; 574 } 575 576 inline bool Environment::inside_should_not_abort_on_uncaught_scope() const { 577 return should_not_abort_scope_counter_ > 0; 578 } 579 580 inline std::vector
* Environment::destroy_async_id_list() { 581 return &destroy_async_id_list_; 582 } 583 584 inline double Environment::new_async_id() { 585 async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1; 586 return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter]; 587 } 588 589 inline double Environment::execution_async_id() { 590 return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId]; 591 } 592 593 inline double Environment::trigger_async_id() { 594 return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId]; 595 } 596 597 inline double Environment::get_default_trigger_async_id() { 598 double default_trigger_async_id = 599 async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; 600 // If defaultTriggerAsyncId isn't set, use the executionAsyncId 601 if (default_trigger_async_id < 0) 602 default_trigger_async_id = execution_async_id(); 603 return default_trigger_async_id; 604 } 605 606 inline double* Environment::heap_statistics_buffer() const { 607 CHECK_NOT_NULL(heap_statistics_buffer_); 608 return heap_statistics_buffer_; 609 } 610 611 inline void Environment::set_heap_statistics_buffer(double* pointer) { 612 CHECK_NULL(heap_statistics_buffer_); // Should be set only once. 613 heap_statistics_buffer_ = pointer; 614 } 615 616 inline double* Environment::heap_space_statistics_buffer() const { 617 CHECK_NOT_NULL(heap_space_statistics_buffer_); 618 return heap_space_statistics_buffer_; 619 } 620 621 inline void Environment::set_heap_space_statistics_buffer(double* pointer) { 622 CHECK_NULL(heap_space_statistics_buffer_); // Should be set only once. 623 heap_space_statistics_buffer_ = pointer; 624 } 625 626 inline double* Environment::heap_code_statistics_buffer() const { 627 CHECK_NOT_NULL(heap_code_statistics_buffer_); 628 return heap_code_statistics_buffer_; 629 } 630 631 inline void Environment::set_heap_code_statistics_buffer(double* pointer) { 632 CHECK_NULL(heap_code_statistics_buffer_); // Should be set only once. 633 heap_code_statistics_buffer_ = pointer; 634 } 635 636 inline char* Environment::http_parser_buffer() const { 637 return http_parser_buffer_; 638 } 639 640 inline void Environment::set_http_parser_buffer(char* buffer) { 641 CHECK_NULL(http_parser_buffer_); // Should be set only once. 642 http_parser_buffer_ = buffer; 643 } 644 645 inline bool Environment::http_parser_buffer_in_use() const { 646 return http_parser_buffer_in_use_; 647 } 648 649 inline void Environment::set_http_parser_buffer_in_use(bool in_use) { 650 http_parser_buffer_in_use_ = in_use; 651 } 652 653 inline http2::Http2State* Environment::http2_state() const { 654 return http2_state_.get(); 655 } 656 657 inline void Environment::set_http2_state( 658 std::unique_ptr
buffer) { 659 CHECK(!http2_state_); // Should be set only once. 660 http2_state_ = std::move(buffer); 661 } 662 663 inline AliasedFloat64Array* Environment::fs_stats_field_array() { 664 return &fs_stats_field_array_; 665 } 666 667 inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() { 668 return &fs_stats_field_bigint_array_; 669 } 670 671 inline std::vector
>& 672 Environment::file_handle_read_wrap_freelist() { 673 return file_handle_read_wrap_freelist_; 674 } 675 676 inline std::shared_ptr
Environment::options() { 677 return options_; 678 } 679 680 inline const std::vector
& Environment::argv() { 681 return argv_; 682 } 683 684 inline const std::vector
& Environment::exec_argv() { 685 return exec_argv_; 686 } 687 688 inline const std::string& Environment::exec_path() const { 689 return exec_path_; 690 } 691 692 #if HAVE_INSPECTOR 693 inline void Environment::set_coverage_directory(const char* dir) { 694 coverage_directory_ = std::string(dir); 695 } 696 697 inline void Environment::set_coverage_connection( 698 std::unique_ptr
connection) { 699 CHECK_NULL(coverage_connection_); 700 std::swap(coverage_connection_, connection); 701 } 702 703 inline profiler::V8CoverageConnection* Environment::coverage_connection() { 704 return coverage_connection_.get(); 705 } 706 707 inline const std::string& Environment::coverage_directory() const { 708 return coverage_directory_; 709 } 710 711 inline void Environment::set_cpu_profiler_connection( 712 std::unique_ptr
connection) { 713 CHECK_NULL(cpu_profiler_connection_); 714 std::swap(cpu_profiler_connection_, connection); 715 } 716 717 inline profiler::V8CpuProfilerConnection* 718 Environment::cpu_profiler_connection() { 719 return cpu_profiler_connection_.get(); 720 } 721 722 inline void Environment::set_cpu_prof_interval(uint64_t interval) { 723 cpu_prof_interval_ = interval; 724 } 725 726 inline uint64_t Environment::cpu_prof_interval() const { 727 return cpu_prof_interval_; 728 } 729 730 inline void Environment::set_cpu_prof_name(const std::string& name) { 731 cpu_prof_name_ = name; 732 } 733 734 inline const std::string& Environment::cpu_prof_name() const { 735 return cpu_prof_name_; 736 } 737 738 inline void Environment::set_cpu_prof_dir(const std::string& dir) { 739 cpu_prof_dir_ = dir; 740 } 741 742 inline const std::string& Environment::cpu_prof_dir() const { 743 return cpu_prof_dir_; 744 } 745 746 inline void Environment::set_heap_profiler_connection( 747 std::unique_ptr
connection) { 748 CHECK_NULL(heap_profiler_connection_); 749 std::swap(heap_profiler_connection_, connection); 750 } 751 752 inline profiler::V8HeapProfilerConnection* 753 Environment::heap_profiler_connection() { 754 return heap_profiler_connection_.get(); 755 } 756 757 inline void Environment::set_heap_prof_name(const std::string& name) { 758 heap_prof_name_ = name; 759 } 760 761 inline const std::string& Environment::heap_prof_name() const { 762 return heap_prof_name_; 763 } 764 765 inline void Environment::set_heap_prof_dir(const std::string& dir) { 766 heap_prof_dir_ = dir; 767 } 768 769 inline const std::string& Environment::heap_prof_dir() const { 770 return heap_prof_dir_; 771 } 772 773 inline void Environment::set_heap_prof_interval(uint64_t interval) { 774 heap_prof_interval_ = interval; 775 } 776 777 inline uint64_t Environment::heap_prof_interval() const { 778 return heap_prof_interval_; 779 } 780 781 #endif // HAVE_INSPECTOR 782 783 inline 784 std::shared_ptr
> Environment::inspector_host_port() { 785 return inspector_host_port_; 786 } 787 788 inline std::shared_ptr
IsolateData::options() { 789 return options_; 790 } 791 792 inline void IsolateData::set_options( 793 std::shared_ptr
options) { 794 options_ = std::move(options); 795 } 796 797 template
798 void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) { 799 auto callback = native_immediates_.CreateCallback(std::move(cb), flags); 800 native_immediates_.Push(std::move(callback)); 801 802 if (flags & CallbackFlags::kRefed) { 803 if (immediate_info()->ref_count() == 0) 804 ToggleImmediateRef(true); 805 immediate_info()->ref_count_inc(1); 806 } 807 } 808 809 template
810 void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) { 811 auto callback = native_immediates_threadsafe_.CreateCallback( 812 std::move(cb), flags); 813 { 814 Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); 815 native_immediates_threadsafe_.Push(std::move(callback)); 816 if (task_queues_async_initialized_) 817 uv_async_send(&task_queues_async_); 818 } 819 } 820 821 template
822 void Environment::RequestInterrupt(Fn&& cb) { 823 auto callback = native_immediates_interrupts_.CreateCallback( 824 std::move(cb), CallbackFlags::kRefed); 825 { 826 Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); 827 native_immediates_interrupts_.Push(std::move(callback)); 828 if (task_queues_async_initialized_) 829 uv_async_send(&task_queues_async_); 830 } 831 RequestInterruptFromV8(); 832 } 833 834 inline bool Environment::can_call_into_js() const { 835 return can_call_into_js_ && !is_stopping(); 836 } 837 838 inline void Environment::set_can_call_into_js(bool can_call_into_js) { 839 can_call_into_js_ = can_call_into_js; 840 } 841 842 inline bool Environment::has_run_bootstrapping_code() const { 843 return has_run_bootstrapping_code_; 844 } 845 846 inline void Environment::set_has_run_bootstrapping_code(bool value) { 847 has_run_bootstrapping_code_ = value; 848 } 849 850 inline bool Environment::has_serialized_options() const { 851 return has_serialized_options_; 852 } 853 854 inline void Environment::set_has_serialized_options(bool value) { 855 has_serialized_options_ = value; 856 } 857 858 inline bool Environment::is_main_thread() const { 859 return worker_context() == nullptr; 860 } 861 862 inline bool Environment::should_not_register_esm_loader() const { 863 return flags_ & EnvironmentFlags::kNoRegisterESMLoader; 864 } 865 866 inline bool Environment::owns_process_state() const { 867 return flags_ & EnvironmentFlags::kOwnsProcessState; 868 } 869 870 inline bool Environment::owns_inspector() const { 871 return flags_ & EnvironmentFlags::kOwnsInspector; 872 } 873 874 inline bool Environment::tracks_unmanaged_fds() const { 875 return flags_ & EnvironmentFlags::kTrackUnmanagedFds; 876 } 877 878 inline uint64_t Environment::thread_id() const { 879 return thread_id_; 880 } 881 882 inline worker::Worker* Environment::worker_context() const { 883 return isolate_data()->worker_context(); 884 } 885 886 inline void Environment::add_sub_worker_context(worker::Worker* context) { 887 sub_worker_contexts_.insert(context); 888 } 889 890 inline void Environment::remove_sub_worker_context(worker::Worker* context) { 891 sub_worker_contexts_.erase(context); 892 } 893 894 template
895 inline void Environment::ForEachWorker(Fn&& iterator) { 896 for (worker::Worker* w : sub_worker_contexts_) iterator(w); 897 } 898 899 inline void Environment::add_refs(int64_t diff) { 900 task_queues_async_refs_ += diff; 901 CHECK_GE(task_queues_async_refs_, 0); 902 if (task_queues_async_refs_ == 0) 903 uv_unref(reinterpret_cast
(&task_queues_async_)); 904 else 905 uv_ref(reinterpret_cast
(&task_queues_async_)); 906 } 907 908 inline bool Environment::is_stopping() const { 909 return is_stopping_.load(); 910 } 911 912 inline void Environment::set_stopping(bool value) { 913 is_stopping_.store(value); 914 } 915 916 inline std::list
* Environment::extra_linked_bindings() { 917 return &extra_linked_bindings_; 918 } 919 920 inline node_module* Environment::extra_linked_bindings_head() { 921 return extra_linked_bindings_.size() > 0 ? 922 &extra_linked_bindings_.front() : nullptr; 923 } 924 925 inline const Mutex& Environment::extra_linked_bindings_mutex() const { 926 return extra_linked_bindings_mutex_; 927 } 928 929 inline performance::PerformanceState* Environment::performance_state() { 930 return performance_state_.get(); 931 } 932 933 inline std::unordered_map
* 934 Environment::performance_marks() { 935 return &performance_marks_; 936 } 937 938 inline IsolateData* Environment::isolate_data() const { 939 return isolate_data_; 940 } 941 942 inline char* Environment::AllocateUnchecked(size_t size) { 943 return static_cast
( 944 isolate_data()->allocator()->AllocateUninitialized(size)); 945 } 946 947 inline char* Environment::Allocate(size_t size) { 948 char* ret = AllocateUnchecked(size); 949 CHECK_NE(ret, nullptr); 950 return ret; 951 } 952 953 inline void Environment::Free(char* data, size_t size) { 954 if (data != nullptr) 955 isolate_data()->allocator()->Free(data, size); 956 } 957 958 inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) { 959 char* data = checked ? Allocate(size) : AllocateUnchecked(size); 960 if (data == nullptr) size = 0; 961 return AllocatedBuffer(this, uv_buf_init(data, size)); 962 } 963 964 inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf) 965 : env_(env), buffer_(buf) {} 966 967 inline void AllocatedBuffer::Resize(size_t len) { 968 // The `len` check is to make sure we don't end up with `nullptr` as our base. 969 char* new_data = env_->Reallocate(buffer_.base, buffer_.len, 970 len > 0 ? len : 1); 971 CHECK_NOT_NULL(new_data); 972 buffer_ = uv_buf_init(new_data, len); 973 } 974 975 inline uv_buf_t AllocatedBuffer::release() { 976 uv_buf_t ret = buffer_; 977 buffer_ = uv_buf_init(nullptr, 0); 978 return ret; 979 } 980 981 inline char* AllocatedBuffer::data() { 982 return buffer_.base; 983 } 984 985 inline const char* AllocatedBuffer::data() const { 986 return buffer_.base; 987 } 988 989 inline size_t AllocatedBuffer::size() const { 990 return buffer_.len; 991 } 992 993 inline AllocatedBuffer::AllocatedBuffer(Environment* env) 994 : env_(env), buffer_(uv_buf_init(nullptr, 0)) {} 995 996 inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other) 997 : AllocatedBuffer() { 998 *this = std::move(other); 999 } 1000 1001 inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) { 1002 clear(); 1003 env_ = other.env_; 1004 buffer_ = other.release(); 1005 return *this; 1006 } 1007 1008 inline AllocatedBuffer::~AllocatedBuffer() { 1009 clear(); 1010 } 1011 1012 inline void AllocatedBuffer::clear() { 1013 uv_buf_t buf = release(); 1014 if (buf.base != nullptr) { 1015 CHECK_NOT_NULL(env_); 1016 env_->Free(buf.base, buf.len); 1017 } 1018 } 1019 1020 // It's a bit awkward to define this Buffer::New() overload here, but it 1021 // avoids a circular dependency with node_internals.h. 1022 namespace Buffer { 1023 v8::MaybeLocal
New(Environment* env, 1024 char* data, 1025 size_t length, 1026 bool uses_malloc); 1027 } 1028 1029 inline v8::MaybeLocal
AllocatedBuffer::ToBuffer() { 1030 CHECK_NOT_NULL(env_); 1031 v8::MaybeLocal
obj = Buffer::New(env_, data(), size(), false); 1032 if (!obj.IsEmpty()) release(); 1033 return obj; 1034 } 1035 1036 inline v8::Local
AllocatedBuffer::ToArrayBuffer() { 1037 CHECK_NOT_NULL(env_); 1038 uv_buf_t buf = release(); 1039 return v8::ArrayBuffer::New(env_->isolate(), 1040 buf.base, 1041 buf.len, 1042 v8::ArrayBufferCreationMode::kInternalized); 1043 } 1044 1045 inline void Environment::ThrowError(const char* errmsg) { 1046 ThrowError(v8::Exception::Error, errmsg); 1047 } 1048 1049 inline void Environment::ThrowTypeError(const char* errmsg) { 1050 ThrowError(v8::Exception::TypeError, errmsg); 1051 } 1052 1053 inline void Environment::ThrowRangeError(const char* errmsg) { 1054 ThrowError(v8::Exception::RangeError, errmsg); 1055 } 1056 1057 inline void Environment::ThrowError( 1058 v8::Local
(*fun)(v8::Local
), 1059 const char* errmsg) { 1060 v8::HandleScope handle_scope(isolate()); 1061 isolate()->ThrowException(fun(OneByteString(isolate(), errmsg))); 1062 } 1063 1064 inline void Environment::ThrowErrnoException(int errorno, 1065 const char* syscall, 1066 const char* message, 1067 const char* path) { 1068 isolate()->ThrowException( 1069 ErrnoException(isolate(), errorno, syscall, message, path)); 1070 } 1071 1072 inline void Environment::ThrowUVException(int errorno, 1073 const char* syscall, 1074 const char* message, 1075 const char* path, 1076 const char* dest) { 1077 isolate()->ThrowException( 1078 UVException(isolate(), errorno, syscall, message, path, dest)); 1079 } 1080 1081 inline v8::Local
1082 Environment::NewFunctionTemplate(v8::FunctionCallback callback, 1083 v8::Local
signature, 1084 v8::ConstructorBehavior behavior, 1085 v8::SideEffectType side_effect_type) { 1086 v8::Local
external = as_callback_data(); 1087 return v8::FunctionTemplate::New(isolate(), callback, external, 1088 signature, 0, behavior, side_effect_type); 1089 } 1090 1091 inline void Environment::SetMethod(v8::Local
that, 1092 const char* name, 1093 v8::FunctionCallback callback) { 1094 v8::Local
context = isolate()->GetCurrentContext(); 1095 v8::Local
function = 1096 NewFunctionTemplate(callback, v8::Local
(), 1097 v8::ConstructorBehavior::kThrow, 1098 v8::SideEffectType::kHasSideEffect) 1099 ->GetFunction(context) 1100 .ToLocalChecked(); 1101 // kInternalized strings are created in the old space. 1102 const v8::NewStringType type = v8::NewStringType::kInternalized; 1103 v8::Local
name_string = 1104 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); 1105 that->Set(context, name_string, function).Check(); 1106 function->SetName(name_string); // NODE_SET_METHOD() compatibility. 1107 } 1108 1109 inline void Environment::SetMethodNoSideEffect(v8::Local
that, 1110 const char* name, 1111 v8::FunctionCallback callback) { 1112 v8::Local
context = isolate()->GetCurrentContext(); 1113 v8::Local
function = 1114 NewFunctionTemplate(callback, v8::Local
(), 1115 v8::ConstructorBehavior::kThrow, 1116 v8::SideEffectType::kHasNoSideEffect) 1117 ->GetFunction(context) 1118 .ToLocalChecked(); 1119 // kInternalized strings are created in the old space. 1120 const v8::NewStringType type = v8::NewStringType::kInternalized; 1121 v8::Local
name_string = 1122 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); 1123 that->Set(context, name_string, function).Check(); 1124 function->SetName(name_string); // NODE_SET_METHOD() compatibility. 1125 } 1126 1127 inline void Environment::SetProtoMethod(v8::Local
that, 1128 const char* name, 1129 v8::FunctionCallback callback) { 1130 v8::Local
signature = v8::Signature::New(isolate(), that); 1131 v8::Local
t = 1132 NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, 1133 v8::SideEffectType::kHasSideEffect); 1134 // kInternalized strings are created in the old space. 1135 const v8::NewStringType type = v8::NewStringType::kInternalized; 1136 v8::Local
name_string = 1137 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); 1138 that->PrototypeTemplate()->Set(name_string, t); 1139 t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. 1140 } 1141 1142 inline void Environment::SetProtoMethodNoSideEffect( 1143 v8::Local
that, 1144 const char* name, 1145 v8::FunctionCallback callback) { 1146 v8::Local
signature = v8::Signature::New(isolate(), that); 1147 v8::Local
t = 1148 NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, 1149 v8::SideEffectType::kHasNoSideEffect); 1150 // kInternalized strings are created in the old space. 1151 const v8::NewStringType type = v8::NewStringType::kInternalized; 1152 v8::Local
name_string = 1153 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); 1154 that->PrototypeTemplate()->Set(name_string, t); 1155 t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. 1156 } 1157 1158 inline void Environment::SetInstanceMethod(v8::Local
that, 1159 const char* name, 1160 v8::FunctionCallback callback) { 1161 v8::Local
signature = v8::Signature::New(isolate(), that); 1162 v8::Local
t = 1163 NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, 1164 v8::SideEffectType::kHasSideEffect); 1165 // kInternalized strings are created in the old space. 1166 const v8::NewStringType type = v8::NewStringType::kInternalized; 1167 v8::Local
name_string = 1168 v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); 1169 that->InstanceTemplate()->Set(name_string, t); 1170 t->SetClassName(name_string); 1171 } 1172 1173 void Environment::AddCleanupHook(void (*fn)(void*), void* arg) { 1174 auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback { 1175 fn, arg, cleanup_hook_counter_++ 1176 }); 1177 // Make sure there was no existing element with these values. 1178 CHECK_EQ(insertion_info.second, true); 1179 } 1180 1181 void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) { 1182 CleanupHookCallback search { fn, arg, 0 }; 1183 cleanup_hooks_.erase(search); 1184 } 1185 1186 inline void Environment::RegisterFinalizationGroupForCleanup( 1187 v8::Local
group) { 1188 cleanup_finalization_groups_.emplace_back(isolate(), group); 1189 DCHECK(task_queues_async_initialized_); 1190 uv_async_send(&task_queues_async_); 1191 } 1192 1193 size_t CleanupHookCallback::Hash::operator()( 1194 const CleanupHookCallback& cb) const { 1195 return std::hash
()(cb.arg_); 1196 } 1197 1198 bool CleanupHookCallback::Equal::operator()( 1199 const CleanupHookCallback& a, const CleanupHookCallback& b) const { 1200 return a.fn_ == b.fn_ && a.arg_ == b.arg_; 1201 } 1202 1203 BaseObject* CleanupHookCallback::GetBaseObject() const { 1204 if (fn_ == BaseObject::DeleteMe) 1205 return static_cast
(arg_); 1206 else 1207 return nullptr; 1208 } 1209 1210 template
1211 void Environment::ForEachBaseObject(T&& iterator) { 1212 for (const auto& hook : cleanup_hooks_) { 1213 BaseObject* obj = hook.GetBaseObject(); 1214 if (obj != nullptr) 1215 iterator(obj); 1216 } 1217 } 1218 1219 void Environment::modify_base_object_count(int64_t delta) { 1220 base_object_count_ += delta; 1221 } 1222 1223 int64_t Environment::base_object_count() const { 1224 return base_object_count_; 1225 } 1226 1227 void Environment::set_main_utf16(std::unique_ptr
str) { 1228 CHECK(!main_utf16_); 1229 main_utf16_ = std::move(str); 1230 } 1231 1232 void Environment::set_process_exit_handler( 1233 std::function
&& handler) { 1234 process_exit_handler_ = std::move(handler); 1235 } 1236 1237 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 1238 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 1239 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 1240 #define V(TypeName, PropertyName) \ 1241 inline \ 1242 v8::Local
IsolateData::PropertyName() const { \ 1243 return PropertyName ## _ .Get(isolate_); \ 1244 } 1245 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 1246 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 1247 PER_ISOLATE_STRING_PROPERTIES(VS) 1248 #undef V 1249 #undef VS 1250 #undef VY 1251 #undef VP 1252 1253 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 1254 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 1255 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 1256 #define V(TypeName, PropertyName) \ 1257 inline v8::Local
Environment::PropertyName() const { \ 1258 return isolate_data()->PropertyName(); \ 1259 } 1260 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 1261 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 1262 PER_ISOLATE_STRING_PROPERTIES(VS) 1263 #undef V 1264 #undef VS 1265 #undef VY 1266 #undef VP 1267 1268 #define V(PropertyName, TypeName) \ 1269 inline v8::Local
Environment::PropertyName() const { \ 1270 return PersistentToLocal::Strong(PropertyName ## _); \ 1271 } \ 1272 inline void Environment::set_ ## PropertyName(v8::Local
value) { \ 1273 PropertyName ## _.Reset(isolate(), value); \ 1274 } 1275 ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V) 1276 ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) 1277 #undef V 1278 1279 inline v8::Local
Environment::context() const { 1280 return PersistentToLocal::Strong(context_); 1281 } 1282 } // namespace node 1283 1284 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 1285 1286 #endif // SRC_ENV_INL_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™