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_H_ 23 #define SRC_ENV_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "aliased_buffer.h" 28 #if HAVE_INSPECTOR 29 #include "inspector_agent.h" 30 #endif 31 #include "handle_wrap.h" 32 #include "req_wrap.h" 33 #include "util.h" 34 #include "uv.h" 35 #include "v8.h" 36 #include "node.h" 37 #include "node_options.h" 38 #include "node_http2_state.h" 39 40 #include <list> 41 #include <stdint.h> 42 #include <vector> 43 #include <unordered_map> 44 #include <unordered_set> 45 46 struct nghttp2_rcbuf; 47 48 namespace node { 49 50 namespace contextify { 51 class ContextifyScript; 52 } 53 54 namespace fs { 55 class FileHandleReadWrap; 56 } 57 58 namespace performance { 59 class performance_state; 60 } 61 62 namespace tracing { 63 class AgentWriterHandle; 64 } 65 66 namespace worker { 67 class Worker; 68 } 69 70 namespace loader { 71 class ModuleWrap; 72 73 struct PackageConfig { 74 enum class Exists { Yes, No }; 75 enum class IsValid { Yes, No }; 76 enum class HasMain { Yes, No }; 77 78 Exists exists; 79 IsValid is_valid; 80 HasMain has_main; 81 std::string main; 82 }; 83 } // namespace loader 84 85 // The number of items passed to push_values_to_array_function has diminishing 86 // returns around 8. This should be used at all call sites using said function. 87 #ifndef NODE_PUSH_VAL_TO_ARRAY_MAX 88 #define NODE_PUSH_VAL_TO_ARRAY_MAX 8 89 #endif 90 91 // PER_ISOLATE_* macros: We have a lot of per-isolate properties 92 // and adding and maintaining their getters and setters by hand would be 93 // difficult so let's make the preprocessor generate them for us. 94 // 95 // In each macro, `V` is expected to be the name of a macro or function which 96 // accepts the number of arguments provided in each tuple in the macro body, 97 // typically two. The named function will be invoked against each tuple. 98 // 99 // Make sure that any macro V defined for use with the PER_ISOLATE_* macros is 100 // undefined again after use. 101 102 // Private symbols are per-isolate primitives but Environment proxies them 103 // for the sake of convenience. Strings should be ASCII-only and have a 104 // "node:" prefix to avoid name clashes with third-party code. 105 #define PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) \ 106 V(alpn_buffer_private_symbol, "node:alpnBuffer") \ 107 V(arrow_message_private_symbol, "node:arrowMessage") \ 108 V(contextify_context_private_symbol, "node:contextify:context") \ 109 V(contextify_global_private_symbol, "node:contextify:global") \ 110 V(decorated_private_symbol, "node:decorated") \ 111 V(napi_wrapper, "node:napi:wrapper") \ 112 V(sab_lifetimepartner_symbol, "node:sharedArrayBufferLifetimePartner") \ 113 114 // Symbols are per-isolate primitives but Environment proxies them 115 // for the sake of convenience. 116 #define PER_ISOLATE_SYMBOL_PROPERTIES(V) \ 117 V(handle_onclose_symbol, "handle_onclose") \ 118 V(oninit_symbol, "oninit") \ 119 V(owner_symbol, "owner") \ 120 121 // Strings are per-isolate primitives but Environment proxies them 122 // for the sake of convenience. Strings should be ASCII-only. 123 #define PER_ISOLATE_STRING_PROPERTIES(V) \ 124 V(address_string, "address") \ 125 V(aliases_string, "aliases") \ 126 V(args_string, "args") \ 127 V(async, "async") \ 128 V(async_ids_stack_string, "async_ids_stack") \ 129 V(buffer_string, "buffer") \ 130 V(bytes_parsed_string, "bytesParsed") \ 131 V(bytes_read_string, "bytesRead") \ 132 V(bytes_string, "bytes") \ 133 V(bytes_written_string, "bytesWritten") \ 134 V(cached_data_produced_string, "cachedDataProduced") \ 135 V(cached_data_rejected_string, "cachedDataRejected") \ 136 V(cached_data_string, "cachedData") \ 137 V(change_string, "change") \ 138 V(channel_string, "channel") \ 139 V(chunks_sent_since_last_write_string, "chunksSentSinceLastWrite") \ 140 V(code_string, "code") \ 141 V(constants_string, "constants") \ 142 V(cwd_string, "cwd") \ 143 V(dest_string, "dest") \ 144 V(destroyed_string, "destroyed") \ 145 V(detached_string, "detached") \ 146 V(dns_a_string, "A") \ 147 V(dns_aaaa_string, "AAAA") \ 148 V(dns_cname_string, "CNAME") \ 149 V(dns_mx_string, "MX") \ 150 V(dns_naptr_string, "NAPTR") \ 151 V(dns_ns_string, "NS") \ 152 V(dns_ptr_string, "PTR") \ 153 V(dns_soa_string, "SOA") \ 154 V(dns_srv_string, "SRV") \ 155 V(dns_txt_string, "TXT") \ 156 V(duration_string, "duration") \ 157 V(emit_warning_string, "emitWarning") \ 158 V(encoding_string, "encoding") \ 159 V(entries_string, "entries") \ 160 V(entry_type_string, "entryType") \ 161 V(env_pairs_string, "envPairs") \ 162 V(env_var_settings_string, "envVarSettings") \ 163 V(errno_string, "errno") \ 164 V(error_string, "error") \ 165 V(exchange_string, "exchange") \ 166 V(exit_code_string, "exitCode") \ 167 V(expire_string, "expire") \ 168 V(exponent_string, "exponent") \ 169 V(exports_string, "exports") \ 170 V(ext_key_usage_string, "ext_key_usage") \ 171 V(external_stream_string, "_externalStream") \ 172 V(family_string, "family") \ 173 V(fatal_exception_string, "_fatalException") \ 174 V(fd_string, "fd") \ 175 V(fields_string, "fields") \ 176 V(file_string, "file") \ 177 V(fingerprint256_string, "fingerprint256") \ 178 V(fingerprint_string, "fingerprint") \ 179 V(flags_string, "flags") \ 180 V(fragment_string, "fragment") \ 181 V(get_data_clone_error_string, "_getDataCloneError") \ 182 V(get_shared_array_buffer_id_string, "_getSharedArrayBufferId") \ 183 V(gid_string, "gid") \ 184 V(handle_string, "handle") \ 185 V(help_text_string, "helpText") \ 186 V(homedir_string, "homedir") \ 187 V(host_string, "host") \ 188 V(hostmaster_string, "hostmaster") \ 189 V(ignore_string, "ignore") \ 190 V(infoaccess_string, "infoAccess") \ 191 V(inherit_string, "inherit") \ 192 V(input_string, "input") \ 193 V(internal_string, "internal") \ 194 V(ipv4_string, "IPv4") \ 195 V(ipv6_string, "IPv6") \ 196 V(isclosing_string, "isClosing") \ 197 V(issuer_string, "issuer") \ 198 V(issuercert_string, "issuerCertificate") \ 199 V(kill_signal_string, "killSignal") \ 200 V(kind_string, "kind") \ 201 V(mac_string, "mac") \ 202 V(main_string, "main") \ 203 V(max_buffer_string, "maxBuffer") \ 204 V(message_port_constructor_string, "MessagePort") \ 205 V(message_port_string, "messagePort") \ 206 V(message_string, "message") \ 207 V(minttl_string, "minttl") \ 208 V(modulus_string, "modulus") \ 209 V(name_string, "name") \ 210 V(netmask_string, "netmask") \ 211 V(nsname_string, "nsname") \ 212 V(ocsp_request_string, "OCSPRequest") \ 213 V(onaltsvc_string, "onaltsvc") \ 214 V(oncertcb_string, "oncertcb") \ 215 V(onchange_string, "onchange") \ 216 V(onclienthello_string, "onclienthello") \ 217 V(oncomplete_string, "oncomplete") \ 218 V(onconnection_string, "onconnection") \ 219 V(ondone_string, "ondone") \ 220 V(onerror_string, "onerror") \ 221 V(onexit_string, "onexit") \ 222 V(onframeerror_string, "onframeerror") \ 223 V(ongetpadding_string, "ongetpadding") \ 224 V(ongoawaydata_string, "ongoawaydata") \ 225 V(onhandshakedone_string, "onhandshakedone") \ 226 V(onhandshakestart_string, "onhandshakestart") \ 227 V(onheaders_string, "onheaders") \ 228 V(onkeylog_string, "onkeylog") \ 229 V(onmessage_string, "onmessage") \ 230 V(onnewsession_string, "onnewsession") \ 231 V(onocspresponse_string, "onocspresponse") \ 232 V(onorigin_string, "onorigin") \ 233 V(onping_string, "onping") \ 234 V(onpriority_string, "onpriority") \ 235 V(onread_string, "onread") \ 236 V(onreadstart_string, "onreadstart") \ 237 V(onreadstop_string, "onreadstop") \ 238 V(onsettings_string, "onsettings") \ 239 V(onshutdown_string, "onshutdown") \ 240 V(onsignal_string, "onsignal") \ 241 V(onstreamclose_string, "onstreamclose") \ 242 V(ontrailers_string, "ontrailers") \ 243 V(onunpipe_string, "onunpipe") \ 244 V(onwrite_string, "onwrite") \ 245 V(openssl_error_stack, "opensslErrorStack") \ 246 V(options_string, "options") \ 247 V(order_string, "order") \ 248 V(output_string, "output") \ 249 V(parse_error_string, "Parse Error") \ 250 V(password_string, "password") \ 251 V(path_string, "path") \ 252 V(pending_handle_string, "pendingHandle") \ 253 V(pid_string, "pid") \ 254 V(pipe_source_string, "pipeSource") \ 255 V(pipe_string, "pipe") \ 256 V(pipe_target_string, "pipeTarget") \ 257 V(port1_string, "port1") \ 258 V(port2_string, "port2") \ 259 V(port_string, "port") \ 260 V(preference_string, "preference") \ 261 V(priority_string, "priority") \ 262 V(promise_string, "promise") \ 263 V(pubkey_string, "pubkey") \ 264 V(query_string, "query") \ 265 V(raw_string, "raw") \ 266 V(read_host_object_string, "_readHostObject") \ 267 V(readable_string, "readable") \ 268 V(refresh_string, "refresh") \ 269 V(regexp_string, "regexp") \ 270 V(rename_string, "rename") \ 271 V(replacement_string, "replacement") \ 272 V(retry_string, "retry") \ 273 V(scheme_string, "scheme") \ 274 V(scopeid_string, "scopeid") \ 275 V(serial_number_string, "serialNumber") \ 276 V(serial_string, "serial") \ 277 V(servername_string, "servername") \ 278 V(service_string, "service") \ 279 V(session_id_string, "sessionId") \ 280 V(shell_string, "shell") \ 281 V(signal_string, "signal") \ 282 V(sink_string, "sink") \ 283 V(size_string, "size") \ 284 V(sni_context_err_string, "Invalid SNI context") \ 285 V(sni_context_string, "sni_context") \ 286 V(source_string, "source") \ 287 V(stack_string, "stack") \ 288 V(start_time_string, "startTime") \ 289 V(status_string, "status") \ 290 V(stdio_string, "stdio") \ 291 V(subject_string, "subject") \ 292 V(subjectaltname_string, "subjectaltname") \ 293 V(syscall_string, "syscall") \ 294 V(thread_id_string, "threadId") \ 295 V(ticketkeycallback_string, "onticketkeycallback") \ 296 V(timeout_string, "timeout") \ 297 V(tls_ticket_string, "tlsTicket") \ 298 V(ttl_string, "ttl") \ 299 V(type_string, "type") \ 300 V(uid_string, "uid") \ 301 V(unknown_string, "<unknown>") \ 302 V(url_string, "url") \ 303 V(username_string, "username") \ 304 V(valid_from_string, "valid_from") \ 305 V(valid_to_string, "valid_to") \ 306 V(value_string, "value") \ 307 V(verify_error_string, "verifyError") \ 308 V(version_string, "version") \ 309 V(weight_string, "weight") \ 310 V(windows_hide_string, "windowsHide") \ 311 V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \ 312 V(wrap_string, "wrap") \ 313 V(writable_string, "writable") \ 314 V(write_host_object_string, "_writeHostObject") \ 315 V(write_queue_size_string, "writeQueueSize") \ 316 V(x_forwarded_string, "x-forwarded-for") \ 317 V(zero_return_string, "ZERO_RETURN") \ 318 319 #define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \ 320 V(as_external, v8::External) \ 321 V(async_hooks_after_function, v8::Function) \ 322 V(async_hooks_before_function, v8::Function) \ 323 V(async_hooks_binding, v8::Object) \ 324 V(async_hooks_destroy_function, v8::Function) \ 325 V(async_hooks_init_function, v8::Function) \ 326 V(async_hooks_promise_resolve_function, v8::Function) \ 327 V(async_wrap_ctor_template, v8::FunctionTemplate) \ 328 V(async_wrap_object_ctor_template, v8::FunctionTemplate) \ 329 V(buffer_prototype_object, v8::Object) \ 330 V(context, v8::Context) \ 331 V(domain_callback, v8::Function) \ 332 V(domexception_function, v8::Function) \ 333 V(fd_constructor_template, v8::ObjectTemplate) \ 334 V(fdclose_constructor_template, v8::ObjectTemplate) \ 335 V(filehandlereadwrap_template, v8::ObjectTemplate) \ 336 V(fs_use_promises_symbol, v8::Symbol) \ 337 V(fsreqpromise_constructor_template, v8::ObjectTemplate) \ 338 V(handle_wrap_ctor_template, v8::FunctionTemplate) \ 339 V(host_import_module_dynamically_callback, v8::Function) \ 340 V(host_initialize_import_meta_object_callback, v8::Function) \ 341 V(http2ping_constructor_template, v8::ObjectTemplate) \ 342 V(http2settings_constructor_template, v8::ObjectTemplate) \ 343 V(http2stream_constructor_template, v8::ObjectTemplate) \ 344 V(immediate_callback_function, v8::Function) \ 345 V(inspector_console_api_object, v8::Object) \ 346 V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \ 347 V(message_port, v8::Object) \ 348 V(message_port_constructor_template, v8::FunctionTemplate) \ 349 V(performance_entry_callback, v8::Function) \ 350 V(performance_entry_template, v8::Function) \ 351 V(pipe_constructor_template, v8::FunctionTemplate) \ 352 V(process_object, v8::Object) \ 353 V(promise_handler_function, v8::Function) \ 354 V(promise_wrap_template, v8::ObjectTemplate) \ 355 V(push_values_to_array_function, v8::Function) \ 356 V(sab_lifetimepartner_constructor_template, v8::FunctionTemplate) \ 357 V(script_context_constructor_template, v8::FunctionTemplate) \ 358 V(script_data_constructor_function, v8::Function) \ 359 V(secure_context_constructor_template, v8::FunctionTemplate) \ 360 V(shutdown_wrap_template, v8::ObjectTemplate) \ 361 V(tcp_constructor_template, v8::FunctionTemplate) \ 362 V(tick_callback_function, v8::Function) \ 363 V(timers_callback_function, v8::Function) \ 364 V(tls_wrap_constructor_function, v8::Function) \ 365 V(tty_constructor_template, v8::FunctionTemplate) \ 366 V(udp_constructor_function, v8::Function) \ 367 V(url_constructor_function, v8::Function) \ 368 V(write_wrap_template, v8::ObjectTemplate) \ 369 370 class Environment; 371 372 class IsolateData { 373 public: 374 IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop, 375 MultiIsolatePlatform* platform = nullptr, 376 uint32_t* zero_fill_field = nullptr); 377 ~IsolateData(); 378 inline uv_loop_t* event_loop() const; 379 inline uint32_t* zero_fill_field() const; 380 inline MultiIsolatePlatform* platform() const; 381 inline std::shared_ptr<PerIsolateOptions> options(); 382 383 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 384 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 385 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 386 #define V(TypeName, PropertyName) \ 387 inline v8::Local<TypeName> PropertyName(v8::Isolate* isolate) const; 388 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 389 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 390 PER_ISOLATE_STRING_PROPERTIES(VS) 391 #undef V 392 #undef VY 393 #undef VS 394 #undef VP 395 396 std::unordered_map<nghttp2_rcbuf*, v8::Eternal<v8::String>> http2_static_strs; 397 inline v8::Isolate* isolate() const; 398 399 private: 400 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 401 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 402 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 403 #define V(TypeName, PropertyName) \ 404 v8::Eternal<TypeName> PropertyName ## _; 405 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) 406 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 407 PER_ISOLATE_STRING_PROPERTIES(VS) 408 #undef V 409 #undef VY 410 #undef VS 411 #undef VP 412 413 v8::Isolate* const isolate_; 414 uv_loop_t* const event_loop_; 415 uint32_t* const zero_fill_field_; 416 MultiIsolatePlatform* platform_; 417 std::shared_ptr<PerIsolateOptions> options_; 418 419 DISALLOW_COPY_AND_ASSIGN(IsolateData); 420 }; 421 422 struct ContextInfo { ContextInfoContextInfo423 explicit ContextInfo(const std::string& name) : name(name) {} 424 const std::string name; 425 std::string origin; 426 bool is_default = false; 427 }; 428 429 struct CompileFnEntry { 430 Environment* env; 431 uint32_t id; 432 CompileFnEntry(Environment* env, uint32_t id); 433 }; 434 435 // Listing the AsyncWrap provider types first enables us to cast directly 436 // from a provider type to a debug category. 437 #define DEBUG_CATEGORY_NAMES(V) \ 438 NODE_ASYNC_PROVIDER_TYPES(V) \ 439 V(INSPECTOR_SERVER) 440 441 enum class DebugCategory { 442 #define V(name) name, 443 DEBUG_CATEGORY_NAMES(V) 444 #undef V 445 CATEGORY_COUNT 446 }; 447 448 class Environment { 449 public: 450 class AsyncHooks { 451 public: 452 // Reason for both UidFields and Fields are that one is stored as a double* 453 // and the other as a uint32_t*. 454 enum Fields { 455 kInit, 456 kBefore, 457 kAfter, 458 kDestroy, 459 kPromiseResolve, 460 kTotals, 461 kCheck, 462 kStackLength, 463 kFieldsCount, 464 }; 465 466 enum UidFields { 467 kExecutionAsyncId, 468 kTriggerAsyncId, 469 kAsyncIdCounter, 470 kDefaultTriggerAsyncId, 471 kUidFieldsCount, 472 }; 473 474 inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields(); 475 inline AliasedBuffer<double, v8::Float64Array>& async_id_fields(); 476 inline AliasedBuffer<double, v8::Float64Array>& async_ids_stack(); 477 478 inline v8::Local<v8::String> provider_string(int idx); 479 480 inline void no_force_checks(); 481 inline Environment* env(); 482 483 inline void push_async_ids(double async_id, double trigger_async_id); 484 inline bool pop_async_id(double async_id); 485 inline void clear_async_id_stack(); // Used in fatal exceptions. 486 487 // Used to set the kDefaultTriggerAsyncId in a scope. This is instead of 488 // passing the trigger_async_id along with other constructor arguments. 489 class DefaultTriggerAsyncIdScope { 490 public: 491 DefaultTriggerAsyncIdScope() = delete; 492 explicit DefaultTriggerAsyncIdScope(Environment* env, 493 double init_trigger_async_id); 494 explicit DefaultTriggerAsyncIdScope(AsyncWrap* async_wrap); 495 ~DefaultTriggerAsyncIdScope(); 496 497 private: 498 AsyncHooks* async_hooks_; 499 double old_default_trigger_async_id_; 500 501 DISALLOW_COPY_AND_ASSIGN(DefaultTriggerAsyncIdScope); 502 }; 503 504 505 private: 506 friend class Environment; // So we can call the constructor. 507 inline AsyncHooks(); 508 // Keep a list of all Persistent strings used for Provider types. 509 v8::Eternal<v8::String> providers_[AsyncWrap::PROVIDERS_LENGTH]; 510 // Keep track of the environment copy itself. 511 Environment* env_; 512 // Stores the ids of the current execution context stack. 513 AliasedBuffer<double, v8::Float64Array> async_ids_stack_; 514 // Attached to a Uint32Array that tracks the number of active hooks for 515 // each type. 516 AliasedBuffer<uint32_t, v8::Uint32Array> fields_; 517 // Attached to a Float64Array that tracks the state of async resources. 518 AliasedBuffer<double, v8::Float64Array> async_id_fields_; 519 520 void grow_async_ids_stack(); 521 522 DISALLOW_COPY_AND_ASSIGN(AsyncHooks); 523 }; 524 525 class AsyncCallbackScope { 526 public: 527 AsyncCallbackScope() = delete; 528 explicit AsyncCallbackScope(Environment* env); 529 ~AsyncCallbackScope(); 530 531 private: 532 Environment* env_; 533 534 DISALLOW_COPY_AND_ASSIGN(AsyncCallbackScope); 535 }; 536 537 inline size_t makecallback_depth() const; 538 539 class ImmediateInfo { 540 public: 541 inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields(); 542 inline uint32_t count() const; 543 inline uint32_t ref_count() const; 544 inline bool has_outstanding() const; 545 546 inline void count_inc(uint32_t increment); 547 inline void count_dec(uint32_t decrement); 548 549 inline void ref_count_inc(uint32_t increment); 550 inline void ref_count_dec(uint32_t decrement); 551 552 private: 553 friend class Environment; // So we can call the constructor. 554 inline explicit ImmediateInfo(v8::Isolate* isolate); 555 556 enum Fields { 557 kCount, 558 kRefCount, 559 kHasOutstanding, 560 kFieldsCount 561 }; 562 563 AliasedBuffer<uint32_t, v8::Uint32Array> fields_; 564 565 DISALLOW_COPY_AND_ASSIGN(ImmediateInfo); 566 }; 567 568 class TickInfo { 569 public: 570 inline AliasedBuffer<uint8_t, v8::Uint8Array>& fields(); 571 inline bool has_scheduled() const; 572 inline bool has_promise_rejections() const; 573 inline bool has_thrown() const; 574 575 inline void promise_rejections_toggle_on(); 576 inline void set_has_thrown(bool state); 577 578 private: 579 friend class Environment; // So we can call the constructor. 580 inline explicit TickInfo(v8::Isolate* isolate); 581 582 enum Fields { 583 kHasScheduled, 584 kHasPromiseRejections, 585 kHasThrown, 586 kFieldsCount 587 }; 588 589 AliasedBuffer<uint8_t, v8::Uint8Array> fields_; 590 591 DISALLOW_COPY_AND_ASSIGN(TickInfo); 592 }; 593 594 static inline Environment* GetCurrent(v8::Isolate* isolate); 595 static inline Environment* GetCurrent(v8::Local<v8::Context> context); 596 static inline Environment* GetCurrent( 597 const v8::FunctionCallbackInfo<v8::Value>& info); 598 599 template <typename T> 600 static inline Environment* GetCurrent( 601 const v8::PropertyCallbackInfo<T>& info); 602 603 static uv_key_t thread_local_env; 604 static inline Environment* GetThreadLocalEnv(); 605 606 Environment(IsolateData* isolate_data, 607 v8::Local<v8::Context> context, 608 tracing::AgentWriterHandle* tracing_agent_writer); 609 ~Environment(); 610 611 void Start(const std::vector<std::string>& args, 612 const std::vector<std::string>& exec_args, 613 bool start_profiler_idle_notifier); 614 615 typedef void (*HandleCleanupCb)(Environment* env, 616 uv_handle_t* handle, 617 void* arg); 618 struct HandleCleanup { 619 uv_handle_t* handle_; 620 HandleCleanupCb cb_; 621 void* arg_; 622 }; 623 624 void RegisterHandleCleanups(); 625 void CleanupHandles(); 626 void Exit(int code); 627 628 // Register clean-up cb to be called on environment destruction. 629 inline void RegisterHandleCleanup(uv_handle_t* handle, 630 HandleCleanupCb cb, 631 void* arg); 632 633 template <typename T, typename OnCloseCallback> 634 inline void CloseHandle(T* handle, OnCloseCallback callback); 635 636 inline void AssignToContext(v8::Local<v8::Context> context, 637 const ContextInfo& info); 638 639 void StartProfilerIdleNotifier(); 640 void StopProfilerIdleNotifier(); 641 inline bool profiler_idle_notifier_started() const; 642 643 inline v8::Isolate* isolate() const; 644 inline tracing::AgentWriterHandle* tracing_agent_writer() const; 645 inline uv_loop_t* event_loop() const; 646 inline uint32_t watched_providers() const; 647 648 static inline Environment* from_immediate_check_handle(uv_check_t* handle); 649 inline uv_check_t* immediate_check_handle(); 650 inline uv_idle_t* immediate_idle_handle(); 651 652 inline void IncreaseWaitingRequestCounter(); 653 inline void DecreaseWaitingRequestCounter(); 654 655 inline AsyncHooks* async_hooks(); 656 inline ImmediateInfo* immediate_info(); 657 inline TickInfo* tick_info(); 658 inline uint64_t timer_base() const; 659 660 inline IsolateData* isolate_data() const; 661 662 inline bool printed_error() const; 663 inline void set_printed_error(bool value); 664 665 void PrintSyncTrace() const; 666 inline void set_trace_sync_io(bool value); 667 668 // This stores whether the --abort-on-uncaught-exception flag was passed 669 // to Node. 670 inline bool abort_on_uncaught_exception() const; 671 inline void set_abort_on_uncaught_exception(bool value); 672 // This is a pseudo-boolean that keeps track of whether an uncaught exception 673 // should abort the process or not if --abort-on-uncaught-exception was 674 // passed to Node. If the flag was not passed, it is ignored. 675 inline AliasedBuffer<uint32_t, v8::Uint32Array>& 676 should_abort_on_uncaught_toggle(); 677 678 // The necessary API for async_hooks. 679 inline double new_async_id(); 680 inline double execution_async_id(); 681 inline double trigger_async_id(); 682 inline double get_default_trigger_async_id(); 683 684 // List of id's that have been destroyed and need the destroy() cb called. 685 inline std::vector<double>* destroy_async_id_list(); 686 687 std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map; 688 std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map; 689 std::unordered_map<uint32_t, contextify::ContextifyScript*> 690 id_to_script_map; 691 std::unordered_set<CompileFnEntry*> compile_fn_entries; 692 std::unordered_map<uint32_t, Persistent<v8::Function>> id_to_function_map; 693 694 inline uint32_t get_next_module_id(); 695 inline uint32_t get_next_script_id(); 696 inline uint32_t get_next_function_id(); 697 698 std::unordered_map<std::string, const loader::PackageConfig> 699 package_json_cache; 700 701 inline double* heap_statistics_buffer() const; 702 inline void set_heap_statistics_buffer(double* pointer); 703 704 inline double* heap_space_statistics_buffer() const; 705 inline void set_heap_space_statistics_buffer(double* pointer); 706 707 inline char* http_parser_buffer() const; 708 inline void set_http_parser_buffer(char* buffer); 709 inline bool http_parser_buffer_in_use() const; 710 inline void set_http_parser_buffer_in_use(bool in_use); 711 712 inline http2::Http2State* http2_state() const; 713 inline void set_http2_state(std::unique_ptr<http2::Http2State> state); 714 715 inline bool debug_enabled(DebugCategory category) const; 716 inline void set_debug_enabled(DebugCategory category, bool enabled); 717 void set_debug_categories(const std::string& cats, bool enabled); 718 719 inline AliasedBuffer<double, v8::Float64Array>* fs_stats_field_array(); 720 inline AliasedBuffer<uint64_t, v8::BigUint64Array>* 721 fs_stats_field_bigint_array(); 722 723 // stat fields contains twice the number of entries because `fs.StatWatcher` 724 // needs room to store data for *two* `fs.Stats` instances. 725 static const int kFsStatsFieldsLength = 14; 726 727 inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>& 728 file_handle_read_wrap_freelist(); 729 730 inline performance::performance_state* performance_state(); 731 inline std::unordered_map<std::string, uint64_t>* performance_marks(); 732 733 void CollectExceptionInfo(v8::Local<v8::Value> context, 734 int errorno, 735 const char* syscall = nullptr, 736 const char* message = nullptr, 737 const char* path = nullptr); 738 739 void CollectUVExceptionInfo(v8::Local<v8::Value> context, 740 int errorno, 741 const char* syscall = nullptr, 742 const char* message = nullptr, 743 const char* path = nullptr, 744 const char* dest = nullptr); 745 746 // If this flag is set, calls into JS (if they would be observable 747 // from userland) must be avoided. This flag does not indicate whether 748 // calling into JS is allowed from a VM perspective at this point. 749 inline bool can_call_into_js() const; 750 inline void set_can_call_into_js(bool can_call_into_js); 751 752 inline bool is_main_thread() const; 753 inline uint64_t thread_id() const; 754 inline void set_thread_id(uint64_t id); 755 inline worker::Worker* worker_context() const; 756 inline void set_worker_context(worker::Worker* context); 757 inline void add_sub_worker_context(worker::Worker* context); 758 inline void remove_sub_worker_context(worker::Worker* context); 759 void stop_sub_worker_contexts(); 760 inline bool is_stopping_worker() const; 761 762 inline void ThrowError(const char* errmsg); 763 inline void ThrowTypeError(const char* errmsg); 764 inline void ThrowRangeError(const char* errmsg); 765 inline void ThrowErrnoException(int errorno, 766 const char* syscall = nullptr, 767 const char* message = nullptr, 768 const char* path = nullptr); 769 inline void ThrowUVException(int errorno, 770 const char* syscall = nullptr, 771 const char* message = nullptr, 772 const char* path = nullptr, 773 const char* dest = nullptr); 774 775 inline v8::Local<v8::FunctionTemplate> 776 NewFunctionTemplate(v8::FunctionCallback callback, 777 v8::Local<v8::Signature> signature = 778 v8::Local<v8::Signature>(), 779 v8::ConstructorBehavior behavior = 780 v8::ConstructorBehavior::kAllow, 781 v8::SideEffectType side_effect = 782 v8::SideEffectType::kHasSideEffect); 783 784 // Convenience methods for NewFunctionTemplate(). 785 inline void SetMethod(v8::Local<v8::Object> that, 786 const char* name, 787 v8::FunctionCallback callback); 788 789 inline void SetProtoMethod(v8::Local<v8::FunctionTemplate> that, 790 const char* name, 791 v8::FunctionCallback callback); 792 inline void SetTemplateMethod(v8::Local<v8::FunctionTemplate> that, 793 const char* name, 794 v8::FunctionCallback callback); 795 796 // Safe variants denote the function has no side effects. 797 inline void SetMethodNoSideEffect(v8::Local<v8::Object> that, 798 const char* name, 799 v8::FunctionCallback callback); 800 inline void SetProtoMethodNoSideEffect(v8::Local<v8::FunctionTemplate> that, 801 const char* name, 802 v8::FunctionCallback callback); 803 inline void SetTemplateMethodNoSideEffect( 804 v8::Local<v8::FunctionTemplate> that, 805 const char* name, 806 v8::FunctionCallback callback); 807 808 void BeforeExit(void (*cb)(void* arg), void* arg); 809 void RunBeforeExitCallbacks(); 810 void AtExit(void (*cb)(void* arg), void* arg); 811 void RunAtExitCallbacks(); 812 813 // Strings and private symbols are shared across shared contexts 814 // The getters simply proxy to the per-isolate primitive. 815 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) 816 #define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) 817 #define VS(PropertyName, StringValue) V(v8::String, PropertyName) 818 #define V(TypeName, PropertyName) \ 819 inline v8::Local<TypeName> PropertyName() const; 820 PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) PER_ISOLATE_SYMBOL_PROPERTIES(VY)821 PER_ISOLATE_SYMBOL_PROPERTIES(VY) 822 PER_ISOLATE_STRING_PROPERTIES(VS) 823 #undef V 824 #undef VS 825 #undef VY 826 #undef VP 827 828 #define V(PropertyName, TypeName) \ 829 inline v8::Local<TypeName> PropertyName() const; \ 830 inline void set_ ## PropertyName(v8::Local<TypeName> value); 831 ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) 832 #undef V 833 834 #if HAVE_INSPECTOR 835 inline inspector::Agent* inspector_agent() const { 836 return inspector_agent_.get(); 837 } 838 #endif 839 840 typedef ListHead<HandleWrap, &HandleWrap::handle_wrap_queue_> HandleWrapQueue; 841 typedef ListHead<ReqWrap<uv_req_t>, &ReqWrap<uv_req_t>::req_wrap_queue_> 842 ReqWrapQueue; 843 handle_wrap_queue()844 inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } req_wrap_queue()845 inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } 846 847 void AddPromiseHook(promise_hook_func fn, void* arg); 848 bool RemovePromiseHook(promise_hook_func fn, void* arg); EmitProcessEnvWarning()849 inline bool EmitProcessEnvWarning() { 850 bool current_value = emit_env_nonstring_warning_; 851 emit_env_nonstring_warning_ = false; 852 return current_value; 853 } 854 855 typedef void (*native_immediate_callback)(Environment* env, void* data); 856 // cb will be called as cb(env, data) on the next event loop iteration. 857 // obj will be kept alive between now and after the callback has run. 858 inline void SetImmediate(native_immediate_callback cb, 859 void* data, 860 v8::Local<v8::Object> obj = v8::Local<v8::Object>()); 861 inline void SetUnrefImmediate(native_immediate_callback cb, 862 void* data, 863 v8::Local<v8::Object> obj = 864 v8::Local<v8::Object>()); 865 // This needs to be available for the JS-land setImmediate(). 866 void ToggleImmediateRef(bool ref); 867 868 class ShouldNotAbortOnUncaughtScope { 869 public: 870 explicit inline ShouldNotAbortOnUncaughtScope(Environment* env); 871 inline void Close(); 872 inline ~ShouldNotAbortOnUncaughtScope(); 873 874 private: 875 Environment* env_; 876 }; 877 878 inline bool inside_should_not_abort_on_uncaught_scope() const; 879 880 static inline Environment* ForAsyncHooks(AsyncHooks* hooks); 881 882 v8::Local<v8::Value> GetNow(); 883 884 inline void AddCleanupHook(void (*fn)(void*), void* arg); 885 inline void RemoveCleanupHook(void (*fn)(void*), void* arg); 886 void RunCleanup(); 887 888 static void BuildEmbedderGraph(v8::Isolate* isolate, 889 v8::EmbedderGraph* graph, 890 void* data); 891 892 inline std::shared_ptr<EnvironmentOptions> options(); 893 894 private: 895 inline void CreateImmediate(native_immediate_callback cb, 896 void* data, 897 v8::Local<v8::Object> obj, 898 bool ref); 899 900 inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), 901 const char* errmsg); 902 903 v8::Isolate* const isolate_; 904 IsolateData* const isolate_data_; 905 tracing::AgentWriterHandle* const tracing_agent_writer_; 906 uv_check_t immediate_check_handle_; 907 uv_idle_t immediate_idle_handle_; 908 uv_prepare_t idle_prepare_handle_; 909 uv_check_t idle_check_handle_; 910 bool profiler_idle_notifier_started_ = false; 911 912 AsyncHooks async_hooks_; 913 ImmediateInfo immediate_info_; 914 TickInfo tick_info_; 915 const uint64_t timer_base_; 916 bool printed_error_; 917 bool abort_on_uncaught_exception_; 918 bool emit_env_nonstring_warning_; 919 size_t makecallback_cntr_; 920 std::vector<double> destroy_async_id_list_; 921 922 std::shared_ptr<EnvironmentOptions> options_; 923 924 uint32_t module_id_counter_ = 0; 925 uint32_t script_id_counter_ = 0; 926 uint32_t function_id_counter_ = 0; 927 928 AliasedBuffer<uint32_t, v8::Uint32Array> should_abort_on_uncaught_toggle_; 929 int should_not_abort_scope_counter_ = 0; 930 931 std::unique_ptr<performance::performance_state> performance_state_; 932 std::unordered_map<std::string, uint64_t> performance_marks_; 933 934 bool can_call_into_js_ = true; 935 uint64_t thread_id_ = 0; 936 std::unordered_set<worker::Worker*> sub_worker_contexts_; 937 938 static void* kNodeContextTagPtr; 939 static int const kNodeContextTag; 940 941 #if HAVE_INSPECTOR 942 std::unique_ptr<inspector::Agent> inspector_agent_; 943 #endif 944 945 // handle_wrap_queue_ and req_wrap_queue_ needs to be at a fixed offset from 946 // the start of the class because it is used by 947 // src/node_postmortem_metadata.cc to calculate offsets and generate debug 948 // symbols for Environment, which assumes that the position of members in 949 // memory are predictable. For more information please refer to 950 // `doc/guides/node-postmortem-support.md` 951 friend int GenDebugSymbols(); 952 HandleWrapQueue handle_wrap_queue_; 953 ReqWrapQueue req_wrap_queue_; 954 std::list<HandleCleanup> handle_cleanup_queue_; 955 int handle_cleanup_waiting_ = 0; 956 int request_waiting_ = 0; 957 958 double* heap_statistics_buffer_ = nullptr; 959 double* heap_space_statistics_buffer_ = nullptr; 960 961 char* http_parser_buffer_; 962 bool http_parser_buffer_in_use_ = false; 963 std::unique_ptr<http2::Http2State> http2_state_; 964 965 bool debug_enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {0}; 966 967 AliasedBuffer<double, v8::Float64Array> fs_stats_field_array_; 968 AliasedBuffer<uint64_t, v8::BigUint64Array> fs_stats_field_bigint_array_; 969 970 std::vector<std::unique_ptr<fs::FileHandleReadWrap>> 971 file_handle_read_wrap_freelist_; 972 973 worker::Worker* worker_context_ = nullptr; 974 975 struct ExitCallback { 976 void (*cb_)(void* arg); 977 void* arg_; 978 }; 979 std::list<ExitCallback> before_exit_functions_; 980 981 std::list<ExitCallback> at_exit_functions_; 982 983 struct PromiseHookCallback { 984 promise_hook_func cb_; 985 void* arg_; 986 size_t enable_count_; 987 }; 988 std::vector<PromiseHookCallback> promise_hooks_; 989 990 struct NativeImmediateCallback { 991 native_immediate_callback cb_; 992 void* data_; 993 v8::Global<v8::Object> keep_alive_; 994 bool refed_; 995 }; 996 std::vector<NativeImmediateCallback> native_immediate_callbacks_; 997 void RunAndClearNativeImmediates(); 998 static void CheckImmediate(uv_check_t* handle); 999 1000 struct CleanupHookCallback { 1001 void (*fn_)(void*); 1002 void* arg_; 1003 1004 // We keep track of the insertion order for these objects, so that we can 1005 // call the callbacks in reverse order when we are cleaning up. 1006 uint64_t insertion_order_counter_; 1007 1008 // Only hashes `arg_`, since that is usually enough to identify the hook. 1009 struct Hash { 1010 inline size_t operator()(const CleanupHookCallback& cb) const; 1011 }; 1012 1013 // Compares by `fn_` and `arg_` being equal. 1014 struct Equal { 1015 inline bool operator()(const CleanupHookCallback& a, 1016 const CleanupHookCallback& b) const; 1017 }; 1018 1019 inline BaseObject* GetBaseObject() const; 1020 }; 1021 1022 // Use an unordered_set, so that we have efficient insertion and removal. 1023 std::unordered_set<CleanupHookCallback, 1024 CleanupHookCallback::Hash, 1025 CleanupHookCallback::Equal> cleanup_hooks_; 1026 uint64_t cleanup_hook_counter_ = 0; 1027 1028 static void EnvPromiseHook(v8::PromiseHookType type, 1029 v8::Local<v8::Promise> promise, 1030 v8::Local<v8::Value> parent); 1031 1032 template <typename T> 1033 void ForEachBaseObject(T&& iterator); 1034 1035 #define V(PropertyName, TypeName) Persistent<TypeName> PropertyName ## _; 1036 ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) 1037 #undef V 1038 1039 DISALLOW_COPY_AND_ASSIGN(Environment); 1040 }; 1041 1042 } // namespace node 1043 1044 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 1045 1046 #endif // SRC_ENV_H_ 1047