Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_internals.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_NODE_INTERNALS_H_ 23 #define SRC_NODE_INTERNALS_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "env.h" 28 #include "node.h" 29 #include "node_binding.h" 30 #include "node_mutex.h" 31 #include "tracing/trace_event.h" 32 #include "util.h" 33 #include "uv.h" 34 #include "v8.h" 35 36 #include <cstdint> 37 #include <cstdlib> 38 39 #include <string> 40 #include <variant> 41 #include <vector> 42 43 struct sockaddr; 44 45 namespace node { 46 47 namespace builtins { 48 class BuiltinLoader; 49 } 50 51 namespace per_process { 52 extern Mutex env_var_mutex; 53 extern uint64_t node_start_time; 54 } // namespace per_process 55 56 // Forward declaration 57 class Environment; 58 59 // Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. 60 // Sets address and port properties on the info object and returns it. 61 // If |info| is omitted, a new object is returned. 62 v8::MaybeLocal<v8::Object> AddressToJS( 63 Environment* env, 64 const sockaddr* addr, 65 v8::Local<v8::Object> info = v8::Local<v8::Object>()); 66 67 template <typename T, int (*F)(const typename T::HandleType*, sockaddr*, int*)> 68 void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>& args) { 69 T* wrap; 70 ASSIGN_OR_RETURN_UNWRAP( 71 &wrap, args.This(), args.GetReturnValue().Set(UV_EBADF)); 72 CHECK(args[0]->IsObject()); 73 sockaddr_storage storage; 74 int addrlen = sizeof(storage); 75 sockaddr* const addr = reinterpret_cast<sockaddr*>(&storage); 76 const int err = F(&wrap->handle_, addr, &addrlen); 77 if (err == 0) 78 AddressToJS(wrap->env(), addr, args[0].As<v8::Object>()); 79 args.GetReturnValue().Set(err); 80 } 81 82 constexpr int kMaxFrameCountForLogging = 10; 83 v8::MaybeLocal<v8::StackTrace> GetCurrentStackTrace( 84 v8::Isolate* isolate, int frame_count = kMaxFrameCountForLogging); 85 86 enum class StackTracePrefix { 87 kAt, // " at " 88 kNumber 89 }; 90 void PrintCurrentStackTrace(v8::Isolate* isolate, 91 StackTracePrefix prefix = StackTracePrefix::kAt); 92 void PrintStackTrace(v8::Isolate* isolate, 93 v8::Local<v8::StackTrace> stack, 94 StackTracePrefix prefix = StackTracePrefix::kAt); 95 void PrintCaughtException(v8::Isolate* isolate, 96 v8::Local<v8::Context> context, 97 const v8::TryCatch& try_catch); 98 std::string FormatCaughtException(v8::Isolate* isolate, 99 v8::Local<v8::Context> context, 100 const v8::TryCatch& try_catch); 101 std::string FormatErrorMessage(v8::Isolate* isolate, 102 v8::Local<v8::Context> context, 103 const std::string& reason, 104 v8::Local<v8::Message> message, 105 bool add_source_line = true); 106 void ResetStdio(); // Safe to call more than once and from signal handlers. 107 #ifdef __POSIX__ 108 void SignalExit(int signal, siginfo_t* info, void* ucontext); 109 #endif 110 111 std::string GetProcessTitle(const char* default_title); 112 std::string GetHumanReadableProcessName(); 113 114 v8::Maybe<void> InitializeBaseContextForSnapshot( 115 v8::Local<v8::Context> context); 116 v8::Maybe<void> InitializeContextRuntime(v8::Local<v8::Context> context); 117 v8::Maybe<void> InitializePrimordials(v8::Local<v8::Context> context, 118 IsolateData* isolate_data); 119 v8::MaybeLocal<v8::Object> InitializePrivateSymbols( 120 v8::Local<v8::Context> context, IsolateData* isolate_data); 121 122 class NodeArrayBufferAllocator : public ArrayBufferAllocator { 123 public: 124 inline uint32_t* zero_fill_field() { return &zero_fill_field_; } 125 126 void* Allocate(size_t size) override; // Defined in src/node.cc 127 void* AllocateUninitialized(size_t size) override; 128 void Free(void* data, size_t size) override; 129 virtual void RegisterPointer(void* data, size_t size) { 130 total_mem_usage_.fetch_add(size, std::memory_order_relaxed); 131 } 132 virtual void UnregisterPointer(void* data, size_t size) { 133 total_mem_usage_.fetch_sub(size, std::memory_order_relaxed); 134 } 135 136 NodeArrayBufferAllocator* GetImpl() final { return this; } 137 inline uint64_t total_mem_usage() const { 138 return total_mem_usage_.load(std::memory_order_relaxed); 139 } 140 141 private: 142 uint32_t zero_fill_field_ = 1; // Boolean but exposed as uint32 to JS land. 143 std::atomic<size_t> total_mem_usage_ {0}; 144 145 // Delegate to V8's allocator for compatibility with the V8 memory cage. 146 std::unique_ptr<v8::ArrayBuffer::Allocator> allocator_{ 147 v8::ArrayBuffer::Allocator::NewDefaultAllocator()}; 148 }; 149 150 class DebuggingArrayBufferAllocator final : public NodeArrayBufferAllocator { 151 public: 152 ~DebuggingArrayBufferAllocator() override; 153 void* Allocate(size_t size) override; 154 void* AllocateUninitialized(size_t size) override; 155 void Free(void* data, size_t size) override; 156 void RegisterPointer(void* data, size_t size) override; 157 void UnregisterPointer(void* data, size_t size) override; 158 159 private: 160 void RegisterPointerInternal(void* data, size_t size); 161 void UnregisterPointerInternal(void* data, size_t size); 162 Mutex mutex_; 163 std::unordered_map<void*, size_t> allocations_; 164 }; 165 166 namespace Buffer { 167 v8::MaybeLocal<v8::Object> Copy(Environment* env, const char* data, size_t len); 168 v8::MaybeLocal<v8::Object> New(Environment* env, size_t size); 169 // Takes ownership of |data|. 170 v8::MaybeLocal<v8::Object> New(Environment* env, 171 char* data, 172 size_t length, 173 void (*callback)(char* data, void* hint), 174 void* hint); 175 // Takes ownership of |data|. Must allocate |data| with the current Isolate's 176 // ArrayBuffer::Allocator(). 177 v8::MaybeLocal<v8::Object> New(Environment* env, 178 char* data, 179 size_t length); 180 // Creates a Buffer instance over an existing ArrayBuffer. 181 v8::MaybeLocal<v8::Uint8Array> New(Environment* env, 182 v8::Local<v8::ArrayBuffer> ab, 183 size_t byte_offset, 184 size_t length); 185 // Construct a Buffer from a MaybeStackBuffer (and also its subclasses like 186 // Utf8Value and TwoByteValue). 187 // If |buf| is invalidated, an empty MaybeLocal is returned, and nothing is 188 // changed. 189 // If |buf| contains actual data, this method takes ownership of |buf|'s 190 // underlying buffer. However, |buf| itself can be reused even after this call, 191 // but its capacity, if increased through AllocateSufficientStorage, is not 192 // guaranteed to stay the same. 193 template <typename T> 194 static v8::MaybeLocal<v8::Object> New(Environment* env, 195 MaybeStackBuffer<T>* buf) { 196 v8::MaybeLocal<v8::Object> ret; 197 char* src = reinterpret_cast<char*>(buf->out()); 198 const size_t len_in_bytes = buf->length() * sizeof(buf->out()[0]); 199 200 if (buf->IsAllocated()) { 201 ret = New(env, src, len_in_bytes); 202 // new always takes ownership of src 203 buf->Release(); 204 } else if (!buf->IsInvalidated()) { 205 ret = Copy(env, src, len_in_bytes); 206 } 207 208 return ret; 209 } 210 } // namespace Buffer 211 212 v8::MaybeLocal<v8::Value> InternalMakeCallback( 213 Environment* env, 214 v8::Local<v8::Object> resource, 215 v8::Local<v8::Object> recv, 216 const v8::Local<v8::Function> callback, 217 int argc, 218 v8::Local<v8::Value> argv[], 219 async_context asyncContext, 220 v8::Local<v8::Value> context_frame); 221 222 v8::MaybeLocal<v8::Value> InternalMakeCallback( 223 v8::Isolate* isolate, 224 v8::Local<v8::Object> recv, 225 const v8::Local<v8::Function> callback, 226 int argc, 227 v8::Local<v8::Value> argv[], 228 async_context asyncContext, 229 v8::Local<v8::Value> context_frame); 230 231 v8::MaybeLocal<v8::Value> MakeSyncCallback(v8::Isolate* isolate, 232 v8::Local<v8::Object> recv, 233 v8::Local<v8::Function> callback, 234 int argc, 235 v8::Local<v8::Value> argv[]); 236 237 class InternalCallbackScope { 238 public: 239 enum Flags { 240 kNoFlags = 0, 241 // Indicates whether 'before' and 'after' hooks should be skipped. 242 kSkipAsyncHooks = 1, 243 // Indicates whether nextTick and microtask queues should be skipped. 244 // This should only be used when there is no call into JS in this scope. 245 // (The HTTP parser also uses it for some weird backwards 246 // compatibility issues, but it shouldn't.) 247 kSkipTaskQueues = 2 248 }; 249 // You need to either guarantee that this `InternalCallbackScope` is 250 // stack-allocated itself, OR that `object` is a pointer to a stack-allocated 251 // `v8::Local<v8::Object>` which outlives this scope (e.g. for the 252 // public `CallbackScope` which indirectly allocates an instance of 253 // this class for ABI stability purposes). 254 InternalCallbackScope( 255 Environment* env, 256 std::variant<v8::Local<v8::Object>, v8::Local<v8::Object>*> object, 257 const async_context& asyncContext, 258 int flags = kNoFlags, 259 v8::Local<v8::Value> context_frame = v8::Local<v8::Value>()); 260 261 // Utility that can be used by AsyncWrap classes. 262 explicit InternalCallbackScope(AsyncWrap* async_wrap, int flags = 0); 263 ~InternalCallbackScope(); 264 void Close(); 265 266 inline bool Failed() const { return failed_; } 267 inline void MarkAsFailed() { failed_ = true; } 268 269 private: 270 Environment* env_; 271 async_context async_context_; 272 v8::Local<v8::Object> object_storage_; 273 v8::Local<v8::Object>* object_; 274 bool skip_hooks_; 275 bool skip_task_queues_; 276 bool failed_ = false; 277 bool pushed_ids_ = false; 278 bool closed_ = false; 279 v8::Global<v8::Value> prior_context_frame_; 280 }; 281 282 class DebugSealHandleScope { 283 public: 284 explicit inline DebugSealHandleScope(v8::Isolate* isolate = nullptr) 285 #ifdef DEBUG 286 : actual_scope_(isolate != nullptr ? isolate : v8::Isolate::GetCurrent()) 287 #endif 288 {} 289 290 private: 291 #ifdef DEBUG 292 v8::SealHandleScope actual_scope_; 293 #endif 294 }; 295 296 class ThreadPoolWork { 297 public: 298 explicit inline ThreadPoolWork(Environment* env, const char* type) 299 : env_(env), type_(type) { 300 CHECK_NOT_NULL(env); 301 } 302 inline virtual ~ThreadPoolWork() = default; 303 304 inline void ScheduleWork(); 305 inline int CancelWork(); 306 307 virtual void DoThreadPoolWork() = 0; 308 virtual void AfterThreadPoolWork(int status) = 0; 309 310 Environment* env() const { return env_; } 311 312 private: 313 Environment* env_; 314 uv_work_t work_req_; 315 const char* type_; 316 }; 317 318 #define TRACING_CATEGORY_NODE "node" 319 #define TRACING_CATEGORY_NODE1(one) \ 320 TRACING_CATEGORY_NODE "," \ 321 TRACING_CATEGORY_NODE "." #one 322 #define TRACING_CATEGORY_NODE2(one, two) \ 323 TRACING_CATEGORY_NODE "," \ 324 TRACING_CATEGORY_NODE "." #one "," \ 325 TRACING_CATEGORY_NODE "." #one "." #two 326 327 // Functions defined in node.cc that are exposed via the bootstrapper object 328 329 #if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__) 330 #define NODE_IMPLEMENTS_POSIX_CREDENTIALS 1 331 #endif // defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__) 332 333 namespace credentials { 334 bool SafeGetenv(const char* key, std::string* text, Environment* env = nullptr); 335 } // namespace credentials 336 337 void TraceEnvVar(Environment* env, const char* message); 338 void TraceEnvVar(Environment* env, const char* message, const char* key); 339 void TraceEnvVar(Environment* env, 340 const char* message, 341 v8::Local<v8::String> key); 342 343 void DefineZlibConstants(v8::Local<v8::Object> target); 344 v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params, 345 uv_loop_t* event_loop, 346 MultiIsolatePlatform* platform, 347 const SnapshotData* snapshot_data = nullptr, 348 const IsolateSettings& settings = {}); 349 // This overload automatically picks the right 'main_script_id' if no callback 350 // was provided by the embedder. 351 v8::MaybeLocal<v8::Value> StartExecution(Environment* env, 352 StartExecutionCallback cb = nullptr); 353 v8::MaybeLocal<v8::Object> GetPerContextExports( 354 v8::Local<v8::Context> context, IsolateData* isolate_data = nullptr); 355 void MarkBootstrapComplete(const v8::FunctionCallbackInfo<v8::Value>& args); 356 357 class InitializationResultImpl final : public InitializationResult { 358 public: 359 ~InitializationResultImpl() = default; 360 int exit_code() const { return static_cast<int>(exit_code_enum()); } 361 ExitCode exit_code_enum() const { return exit_code_; } 362 bool early_return() const { return early_return_; } 363 const std::vector<std::string>& args() const { return args_; } 364 const std::vector<std::string>& exec_args() const { return exec_args_; } 365 const std::vector<std::string>& errors() const { return errors_; } 366 MultiIsolatePlatform* platform() const { return platform_; } 367 368 ExitCode exit_code_ = ExitCode::kNoFailure; 369 std::vector<std::string> args_; 370 std::vector<std::string> exec_args_; 371 std::vector<std::string> errors_; 372 bool early_return_ = false; 373 MultiIsolatePlatform* platform_ = nullptr; 374 }; 375 376 void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s); 377 void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s); 378 void SetIsolateCreateParamsForNode(v8::Isolate::CreateParams* params); 379 380 #if HAVE_INSPECTOR 381 namespace profiler { 382 void StartProfilers(Environment* env); 383 } 384 #endif // HAVE_INSPECTOR 385 386 #ifdef __POSIX__ 387 static constexpr unsigned kMaxSignal = 32; 388 #endif 389 390 bool HasSignalJSHandler(int signum); 391 392 #ifdef _WIN32 393 typedef SYSTEMTIME TIME_TYPE; 394 #else // UNIX, macOS 395 typedef struct tm TIME_TYPE; 396 #endif 397 398 double GetCurrentTimeInMicroseconds(); 399 int WriteFileSync(const char* path, uv_buf_t* bufs, size_t buf_count); 400 int WriteFileSync(const char* path, uv_buf_t buf); 401 int WriteFileSync(v8::Isolate* isolate, 402 const char* path, 403 v8::Local<v8::String> string); 404 405 class DiagnosticFilename { 406 public: 407 static void LocalTime(TIME_TYPE* tm_struct); 408 409 inline DiagnosticFilename(Environment* env, 410 const char* prefix, 411 const char* ext); 412 413 inline DiagnosticFilename(uint64_t thread_id, 414 const char* prefix, 415 const char* ext); 416 417 inline const char* operator*() const; 418 419 private: 420 static std::string MakeFilename( 421 uint64_t thread_id, 422 const char* prefix, 423 const char* ext); 424 425 std::string filename_; 426 }; 427 428 namespace heap { 429 v8::Maybe<void> WriteSnapshot(Environment* env, 430 const char* filename, 431 v8::HeapProfiler::HeapSnapshotOptions options); 432 } 433 434 namespace heap { 435 436 void DeleteHeapSnapshot(const v8::HeapSnapshot* snapshot); 437 using HeapSnapshotPointer = 438 DeleteFnPtr<const v8::HeapSnapshot, DeleteHeapSnapshot>; 439 440 BaseObjectPtr<AsyncWrap> CreateHeapSnapshotStream( 441 Environment* env, HeapSnapshotPointer&& snapshot); 442 } // namespace heap 443 444 node_module napi_module_to_node_module(const napi_module* mod); 445 446 std::ostream& operator<<(std::ostream& output, const SnapshotFlags& flags); 447 std::ostream& operator<<(std::ostream& output, 448 const std::vector<SnapshotIndex>& v); 449 std::ostream& operator<<(std::ostream& output, 450 const std::vector<std::string>& vec); 451 std::ostream& operator<<(std::ostream& output, 452 const std::vector<PropInfo>& vec); 453 std::ostream& operator<<(std::ostream& output, const PropInfo& d); 454 std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& d); 455 std::ostream& operator<<(std::ostream& output, 456 const ImmediateInfo::SerializeInfo& d); 457 std::ostream& operator<<(std::ostream& output, 458 const TickInfo::SerializeInfo& d); 459 std::ostream& operator<<(std::ostream& output, 460 const AsyncHooks::SerializeInfo& d); 461 std::ostream& operator<<(std::ostream& output, const SnapshotMetadata& d); 462 463 namespace performance { 464 std::ostream& operator<<(std::ostream& output, 465 const PerformanceState::SerializeInfo& d); 466 } 467 468 bool linux_at_secure(); 469 470 namespace heap { 471 v8::HeapProfiler::HeapSnapshotOptions GetHeapSnapshotOptions( 472 v8::Local<v8::Value> options); 473 } // namespace heap 474 475 enum encoding ParseEncoding(v8::Isolate* isolate, 476 v8::Local<v8::Value> encoding_v, 477 v8::Local<v8::Value> encoding_id, 478 enum encoding default_encoding); 479 } // namespace node 480 481 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 482 483 #endif // SRC_NODE_INTERNALS_H_