Viewing file: node_internals.h (13.34 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SRC_NODE_INTERNALS_H_ #define SRC_NODE_INTERNALS_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "env.h" #include "node.h" #include "node_binding.h" #include "node_mutex.h" #include "tracing/trace_event.h" #include "util.h" #include "uv.h" #include "v8.h"
#include <cstdint> #include <cstdlib>
#include <string> #include <vector>
// Custom constants used by both node_constants.cc and node_zlib.cc #define Z_MIN_WINDOWBITS 8 #define Z_MAX_WINDOWBITS 15 #define Z_DEFAULT_WINDOWBITS 15
struct sockaddr;
namespace node {
namespace native_module { class NativeModuleLoader; }
namespace per_process { extern Mutex env_var_mutex; extern uint64_t node_start_time; extern bool v8_is_profiling; } // namespace per_process
// Forward declaration class Environment;
// Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. // Sets address and port properties on the info object and returns it. // If |info| is omitted, a new object is returned. v8::Local<v8::Object> AddressToJS( Environment* env, const sockaddr* addr, v8::Local<v8::Object> info = v8::Local<v8::Object>());
template <typename T, int (*F)(const typename T::HandleType*, sockaddr*, int*)> void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>& args) { T* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder(), args.GetReturnValue().Set(UV_EBADF)); CHECK(args[0]->IsObject()); sockaddr_storage storage; int addrlen = sizeof(storage); sockaddr* const addr = reinterpret_cast<sockaddr*>(&storage); const int err = F(&wrap->handle_, addr, &addrlen); if (err == 0) AddressToJS(wrap->env(), addr, args[0].As<v8::Object>()); args.GetReturnValue().Set(err); }
void PrintStackTrace(v8::Isolate* isolate, v8::Local<v8::StackTrace> stack); void PrintCaughtException(v8::Isolate* isolate, v8::Local<v8::Context> context, const v8::TryCatch& try_catch);
void ResetStdio(); // Safe to call more than once and from signal handlers. void SignalExit(int signo); #ifdef __POSIX__ void RegisterSignalHandler(int signal, void (*handler)(int signal), bool reset_handler = false); #endif
std::string GetProcessTitle(const char* default_title); std::string GetHumanReadableProcessName();
void InitializeContextRuntime(v8::Local<v8::Context>); bool InitializePrimordials(v8::Local<v8::Context> context);
class NodeArrayBufferAllocator : public ArrayBufferAllocator { public: inline uint32_t* zero_fill_field() { return &zero_fill_field_; }
void* Allocate(size_t size) override; // Defined in src/node.cc void* AllocateUninitialized(size_t size) override; void Free(void* data, size_t size) override; virtual void* Reallocate(void* data, size_t old_size, size_t size); virtual void RegisterPointer(void* data, size_t size) { total_mem_usage_.fetch_add(size, std::memory_order_relaxed); } virtual void UnregisterPointer(void* data, size_t size) { total_mem_usage_.fetch_sub(size, std::memory_order_relaxed); }
NodeArrayBufferAllocator* GetImpl() final { return this; } inline uint64_t total_mem_usage() const { return total_mem_usage_.load(std::memory_order_relaxed); }
private: uint32_t zero_fill_field_ = 1; // Boolean but exposed as uint32 to JS land. std::atomic<size_t> total_mem_usage_ {0}; };
class DebuggingArrayBufferAllocator final : public NodeArrayBufferAllocator { public: ~DebuggingArrayBufferAllocator() override; void* Allocate(size_t size) override; void* AllocateUninitialized(size_t size) override; void Free(void* data, size_t size) override; void* Reallocate(void* data, size_t old_size, size_t size) override; void RegisterPointer(void* data, size_t size) override; void UnregisterPointer(void* data, size_t size) override;
private: void RegisterPointerInternal(void* data, size_t size); void UnregisterPointerInternal(void* data, size_t size); Mutex mutex_; std::unordered_map<void*, size_t> allocations_; };
namespace Buffer { v8::MaybeLocal<v8::Object> Copy(Environment* env, const char* data, size_t len); v8::MaybeLocal<v8::Object> New(Environment* env, size_t size); // Takes ownership of |data|. v8::MaybeLocal<v8::Object> New(Environment* env, char* data, size_t length, void (*callback)(char* data, void* hint), void* hint); // Takes ownership of |data|. Must allocate |data| with the current Isolate's // ArrayBuffer::Allocator(). v8::MaybeLocal<v8::Object> New(Environment* env, char* data, size_t length, bool uses_malloc); // Creates a Buffer instance over an existing ArrayBuffer. v8::MaybeLocal<v8::Uint8Array> New(Environment* env, v8::Local<v8::ArrayBuffer> ab, size_t byte_offset, size_t length); // Construct a Buffer from a MaybeStackBuffer (and also its subclasses like // Utf8Value and TwoByteValue). // If |buf| is invalidated, an empty MaybeLocal is returned, and nothing is // changed. // If |buf| contains actual data, this method takes ownership of |buf|'s // underlying buffer. However, |buf| itself can be reused even after this call, // but its capacity, if increased through AllocateSufficientStorage, is not // guaranteed to stay the same. template <typename T> static v8::MaybeLocal<v8::Object> New(Environment* env, MaybeStackBuffer<T>* buf) { v8::MaybeLocal<v8::Object> ret; char* src = reinterpret_cast<char*>(buf->out()); const size_t len_in_bytes = buf->length() * sizeof(buf->out()[0]);
if (buf->IsAllocated()) ret = New(env, src, len_in_bytes, true); else if (!buf->IsInvalidated()) ret = Copy(env, src, len_in_bytes);
if (ret.IsEmpty()) return ret;
if (buf->IsAllocated()) buf->Release();
return ret; } } // namespace Buffer
v8::MaybeLocal<v8::Value> InternalMakeCallback( Environment* env, v8::Local<v8::Object> resource, v8::Local<v8::Object> recv, const v8::Local<v8::Function> callback, int argc, v8::Local<v8::Value> argv[], async_context asyncContext);
class InternalCallbackScope { public: enum Flags { kNoFlags = 0, // Indicates whether 'before' and 'after' hooks should be skipped. kSkipAsyncHooks = 1, // Indicates whether nextTick and microtask queues should be skipped. // This should only be used when there is no call into JS in this scope. // (The HTTP parser also uses it for some weird backwards // compatibility issues, but it shouldn't.) kSkipTaskQueues = 2 }; InternalCallbackScope(Environment* env, v8::Local<v8::Object> object, const async_context& asyncContext, int flags = kNoFlags); // Utility that can be used by AsyncWrap classes. explicit InternalCallbackScope(AsyncWrap* async_wrap, int flags = 0); ~InternalCallbackScope(); void Close();
inline bool Failed() const { return failed_; } inline void MarkAsFailed() { failed_ = true; }
private: Environment* env_; async_context async_context_; v8::Local<v8::Object> object_; bool skip_hooks_; bool skip_task_queues_; bool failed_ = false; bool pushed_ids_ = false; bool closed_ = false; };
class DebugSealHandleScope { public: explicit inline DebugSealHandleScope(v8::Isolate* isolate = nullptr) #ifdef DEBUG : actual_scope_(isolate != nullptr ? isolate : v8::Isolate::GetCurrent()) #endif {}
private: #ifdef DEBUG v8::SealHandleScope actual_scope_; #endif };
class ThreadPoolWork { public: explicit inline ThreadPoolWork(Environment* env) : env_(env) { CHECK_NOT_NULL(env); } inline virtual ~ThreadPoolWork() = default;
inline void ScheduleWork(); inline int CancelWork();
virtual void DoThreadPoolWork() = 0; virtual void AfterThreadPoolWork(int status) = 0;
Environment* env() const { return env_; }
private: Environment* env_; uv_work_t work_req_; };
#define TRACING_CATEGORY_NODE "node" #define TRACING_CATEGORY_NODE1(one) \ TRACING_CATEGORY_NODE "," \ TRACING_CATEGORY_NODE "." #one #define TRACING_CATEGORY_NODE2(one, two) \ TRACING_CATEGORY_NODE "," \ TRACING_CATEGORY_NODE "." #one "," \ TRACING_CATEGORY_NODE "." #one "." #two
// Functions defined in node.cc that are exposed via the bootstrapper object
#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__) #define NODE_IMPLEMENTS_POSIX_CREDENTIALS 1 #endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
namespace credentials { bool SafeGetenv(const char* key, std::string* text, Environment* env = nullptr); } // namespace credentials
void DefineZlibConstants(v8::Local<v8::Object> target); v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params, uv_loop_t* event_loop, MultiIsolatePlatform* platform); // This overload automatically picks the right 'main_script_id' if no callback // was provided by the embedder. v8::MaybeLocal<v8::Value> StartExecution(Environment* env, StartExecutionCallback cb = nullptr); v8::MaybeLocal<v8::Object> GetPerContextExports(v8::Local<v8::Context> context); v8::MaybeLocal<v8::Value> ExecuteBootstrapper( Environment* env, const char* id, std::vector<v8::Local<v8::String>>* parameters, std::vector<v8::Local<v8::Value>>* arguments); void MarkBootstrapComplete(const v8::FunctionCallbackInfo<v8::Value>& args);
struct InitializationResult { int exit_code = 0; std::vector<std::string> args; std::vector<std::string> exec_args; bool early_return = false; }; InitializationResult InitializeOncePerProcess(int argc, char** argv); void TearDownOncePerProcess(); void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s); void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s); void SetIsolateCreateParamsForNode(v8::Isolate::CreateParams* params);
#if HAVE_INSPECTOR namespace profiler { void StartProfilers(Environment* env); } #endif // HAVE_INSPECTOR
#ifdef __POSIX__ static constexpr unsigned kMaxSignal = 32; #endif
bool HasSignalJSHandler(int signum);
#ifdef _WIN32 typedef SYSTEMTIME TIME_TYPE; #else // UNIX, OSX typedef struct tm TIME_TYPE; #endif
double GetCurrentTimeInMicroseconds(); int WriteFileSync(const char* path, uv_buf_t buf); int WriteFileSync(v8::Isolate* isolate, const char* path, v8::Local<v8::String> string);
class DiagnosticFilename { public: static void LocalTime(TIME_TYPE* tm_struct);
inline DiagnosticFilename(Environment* env, const char* prefix, const char* ext);
inline DiagnosticFilename(uint64_t thread_id, const char* prefix, const char* ext);
inline const char* operator*() const;
private: static std::string MakeFilename( uint64_t thread_id, const char* prefix, const char* ext);
std::string filename_; };
class TraceEventScope { public: TraceEventScope(const char* category, const char* name, void* id) : category_(category), name_(name), id_(id) { TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_, name_, id_); } ~TraceEventScope() { TRACE_EVENT_NESTABLE_ASYNC_END0(category_, name_, id_); }
private: const char* category_; const char* name_; void* id_; };
namespace heap {
void DeleteHeapSnapshot(const v8::HeapSnapshot* snapshot); using HeapSnapshotPointer = DeleteFnPtr<const v8::HeapSnapshot, DeleteHeapSnapshot>;
BaseObjectPtr<AsyncWrap> CreateHeapSnapshotStream( Environment* env, HeapSnapshotPointer&& snapshot); } // namespace heap
namespace fs { std::string Basename(const std::string& str, const std::string& extension); } // namespace fs
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_NODE_INTERNALS_H_
|