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