@encharm/cws 4.3.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/dist/bindings/cws_darwin_arm64_node108.node +0 -0
- package/dist/bindings/cws_darwin_arm64_node115.node +0 -0
- package/dist/bindings/cws_darwin_arm64_node83.node +0 -0
- package/dist/bindings/cws_darwin_arm64_node93.node +0 -0
- package/dist/bindings/cws_darwin_x64_node108.node +0 -0
- package/dist/bindings/cws_darwin_x64_node115.node +0 -0
- package/dist/bindings/cws_darwin_x64_node83.node +0 -0
- package/dist/bindings/cws_darwin_x64_node93.node +0 -0
- package/dist/bindings/cws_linux_arm64_node108.node +0 -0
- package/dist/bindings/cws_linux_arm64_node115.node +0 -0
- package/dist/bindings/cws_linux_arm64_node83.node +0 -0
- package/dist/bindings/cws_linux_arm64_node93.node +0 -0
- package/dist/bindings/cws_linux_x64_node108.node +0 -0
- package/dist/bindings/cws_linux_x64_node115.node +0 -0
- package/dist/bindings/cws_linux_x64_node83.node +0 -0
- package/dist/bindings/cws_linux_x64_node93.node +0 -0
- package/dist/bindings/cws_win32_x64_node108.node +0 -0
- package/dist/bindings/cws_win32_x64_node115.node +0 -0
- package/dist/bindings/cws_win32_x64_node83.node +0 -0
- package/dist/bindings/cws_win32_x64_node93.node +0 -0
- package/dist/shared.js +1 -1
- package/package.json +5 -5
- package/src/Addon.cpp +4 -12
- package/src/Addon.h +67 -91
- package/src/Socket.h +1 -0
- package/src/cSNode.cpp +3 -8
- package/src/headers/20/acorn_version.h +6 -0
- package/src/headers/20/aliased_buffer-inl.h +243 -0
- package/src/headers/20/aliased_buffer.h +206 -0
- package/src/headers/20/aliased_struct-inl.h +54 -0
- package/src/headers/20/aliased_struct.h +63 -0
- package/src/headers/20/async_wrap-inl.h +93 -0
- package/src/headers/20/async_wrap.h +252 -0
- package/src/headers/20/base64-inl.h +193 -0
- package/src/headers/20/base64.h +53 -0
- package/src/headers/20/base64_version.h +6 -0
- package/src/headers/20/base_object-inl.h +316 -0
- package/src/headers/20/base_object.h +320 -0
- package/src/headers/20/base_object_types.h +73 -0
- package/src/headers/20/blob_serializer_deserializer-inl.h +361 -0
- package/src/headers/20/blob_serializer_deserializer.h +132 -0
- package/src/headers/20/callback_queue-inl.h +97 -0
- package/src/headers/20/callback_queue.h +79 -0
- package/src/headers/20/cares_wrap.h +524 -0
- package/src/headers/20/cjs_module_lexer_version.h +6 -0
- package/src/headers/20/cleanup_queue-inl.h +62 -0
- package/src/headers/20/cleanup_queue.h +85 -0
- package/src/headers/20/connect_wrap.h +26 -0
- package/src/headers/20/connection_wrap.h +30 -0
- package/src/headers/20/cppgc/DEPS +8 -0
- package/src/headers/20/cppgc/OWNERS +2 -0
- package/src/headers/20/cppgc/README.md +135 -0
- package/src/headers/20/cppgc/allocation.h +310 -0
- package/src/headers/20/cppgc/common.h +28 -0
- package/src/headers/20/cppgc/cross-thread-persistent.h +466 -0
- package/src/headers/20/cppgc/custom-space.h +97 -0
- package/src/headers/20/cppgc/default-platform.h +67 -0
- package/src/headers/20/cppgc/ephemeron-pair.h +30 -0
- package/src/headers/20/cppgc/explicit-management.h +100 -0
- package/src/headers/20/cppgc/garbage-collected.h +106 -0
- package/src/headers/20/cppgc/heap-consistency.h +309 -0
- package/src/headers/20/cppgc/heap-handle.h +48 -0
- package/src/headers/20/cppgc/heap-state.h +82 -0
- package/src/headers/20/cppgc/heap-statistics.h +120 -0
- package/src/headers/20/cppgc/heap.h +202 -0
- package/src/headers/20/cppgc/internal/api-constants.h +68 -0
- package/src/headers/20/cppgc/internal/atomic-entry-flag.h +48 -0
- package/src/headers/20/cppgc/internal/base-page-handle.h +45 -0
- package/src/headers/20/cppgc/internal/caged-heap-local-data.h +111 -0
- package/src/headers/20/cppgc/internal/caged-heap.h +61 -0
- package/src/headers/20/cppgc/internal/compiler-specific.h +38 -0
- package/src/headers/20/cppgc/internal/finalizer-trait.h +93 -0
- package/src/headers/20/cppgc/internal/gc-info.h +157 -0
- package/src/headers/20/cppgc/internal/logging.h +50 -0
- package/src/headers/20/cppgc/internal/member-storage.h +248 -0
- package/src/headers/20/cppgc/internal/name-trait.h +137 -0
- package/src/headers/20/cppgc/internal/persistent-node.h +214 -0
- package/src/headers/20/cppgc/internal/pointer-policies.h +243 -0
- package/src/headers/20/cppgc/internal/write-barrier.h +487 -0
- package/src/headers/20/cppgc/liveness-broker.h +78 -0
- package/src/headers/20/cppgc/macros.h +35 -0
- package/src/headers/20/cppgc/member.h +604 -0
- package/src/headers/20/cppgc/name-provider.h +65 -0
- package/src/headers/20/cppgc/object-size-trait.h +58 -0
- package/src/headers/20/cppgc/persistent.h +373 -0
- package/src/headers/20/cppgc/platform.h +158 -0
- package/src/headers/20/cppgc/prefinalizer.h +75 -0
- package/src/headers/20/cppgc/process-heap-statistics.h +36 -0
- package/src/headers/20/cppgc/sentinel-pointer.h +32 -0
- package/src/headers/20/cppgc/source-location.h +92 -0
- package/src/headers/20/cppgc/testing.h +106 -0
- package/src/headers/20/cppgc/trace-trait.h +120 -0
- package/src/headers/20/cppgc/type-traits.h +250 -0
- package/src/headers/20/cppgc/visitor.h +426 -0
- package/src/headers/20/crypto/crypto_clienthello.h +131 -0
- package/src/headers/20/crypto/crypto_context.h +160 -0
- package/src/headers/20/crypto/crypto_keys.h +419 -0
- package/src/headers/20/crypto/crypto_tls.h +304 -0
- package/src/headers/20/crypto/crypto_util.h +806 -0
- package/src/headers/20/crypto_clienthello.h +131 -0
- package/src/headers/20/debug_utils-inl.h +226 -0
- package/src/headers/20/debug_utils.h +188 -0
- package/src/headers/20/diagnosticfilename-inl.h +33 -0
- package/src/headers/20/encoding_binding.h +59 -0
- package/src/headers/20/env-inl.h +923 -0
- package/src/headers/20/env.h +1193 -0
- package/src/headers/20/env_properties.h +446 -0
- package/src/headers/20/handle_wrap.h +123 -0
- package/src/headers/20/histogram-inl.h +107 -0
- package/src/headers/20/histogram.h +240 -0
- package/src/headers/20/inspector_agent.h +144 -0
- package/src/headers/20/inspector_io.h +78 -0
- package/src/headers/20/inspector_profiler.h +149 -0
- package/src/headers/20/inspector_socket.h +60 -0
- package/src/headers/20/inspector_socket_server.h +110 -0
- package/src/headers/20/js_native_api.h +601 -0
- package/src/headers/20/js_native_api_types.h +168 -0
- package/src/headers/20/js_native_api_v8.h +463 -0
- package/src/headers/20/js_native_api_v8_internals.h +45 -0
- package/src/headers/20/js_stream.h +52 -0
- package/src/headers/20/json_parser.h +38 -0
- package/src/headers/20/json_utils.h +172 -0
- package/src/headers/20/memory_tracker-inl.h +356 -0
- package/src/headers/20/memory_tracker.h +289 -0
- package/src/headers/20/module_wrap.h +117 -0
- package/src/headers/20/node.h +1516 -0
- package/src/headers/20/node_api.h +261 -0
- package/src/headers/20/node_api_internals.h +42 -0
- package/src/headers/20/node_api_types.h +52 -0
- package/src/headers/20/node_binding.h +142 -0
- package/src/headers/20/node_blob.h +159 -0
- package/src/headers/20/node_bob-inl.h +36 -0
- package/src/headers/20/node_bob.h +107 -0
- package/src/headers/20/node_buffer.h +92 -0
- package/src/headers/20/node_builtins.h +197 -0
- package/src/headers/20/node_constants.h +82 -0
- package/src/headers/20/node_context_data.h +98 -0
- package/src/headers/20/node_contextify.h +206 -0
- package/src/headers/20/node_crypto.h +56 -0
- package/src/headers/20/node_dir.h +52 -0
- package/src/headers/20/node_dotenv.h +37 -0
- package/src/headers/20/node_errors.h +313 -0
- package/src/headers/20/node_exit_code.h +54 -0
- package/src/headers/20/node_external_reference.h +172 -0
- package/src/headers/20/node_file-inl.h +389 -0
- package/src/headers/20/node_file.h +537 -0
- package/src/headers/20/node_http2.h +1146 -0
- package/src/headers/20/node_http2_state.h +147 -0
- package/src/headers/20/node_http_common-inl.h +201 -0
- package/src/headers/20/node_http_common.h +532 -0
- package/src/headers/20/node_i18n.h +145 -0
- package/src/headers/20/node_internals.h +443 -0
- package/src/headers/20/node_main_instance.h +67 -0
- package/src/headers/20/node_mem-inl.h +112 -0
- package/src/headers/20/node_mem.h +45 -0
- package/src/headers/20/node_messaging.h +377 -0
- package/src/headers/20/node_metadata.h +138 -0
- package/src/headers/20/node_mutex.h +323 -0
- package/src/headers/20/node_object_wrap.h +132 -0
- package/src/headers/20/node_options-inl.h +478 -0
- package/src/headers/20/node_options.h +538 -0
- package/src/headers/20/node_perf.h +166 -0
- package/src/headers/20/node_perf_common.h +98 -0
- package/src/headers/20/node_platform.h +195 -0
- package/src/headers/20/node_process-inl.h +26 -0
- package/src/headers/20/node_process.h +99 -0
- package/src/headers/20/node_realm-inl.h +139 -0
- package/src/headers/20/node_realm.h +184 -0
- package/src/headers/20/node_report.h +42 -0
- package/src/headers/20/node_revert.h +82 -0
- package/src/headers/20/node_root_certs.h +3443 -0
- package/src/headers/20/node_sea.h +56 -0
- package/src/headers/20/node_shadow_realm.h +46 -0
- package/src/headers/20/node_snapshot_builder.h +54 -0
- package/src/headers/20/node_snapshotable.h +164 -0
- package/src/headers/20/node_sockaddr-inl.h +266 -0
- package/src/headers/20/node_sockaddr.h +405 -0
- package/src/headers/20/node_stat_watcher.h +73 -0
- package/src/headers/20/node_threadsafe_cow-inl.h +54 -0
- package/src/headers/20/node_threadsafe_cow.h +105 -0
- package/src/headers/20/node_union_bytes.h +81 -0
- package/src/headers/20/node_url.h +92 -0
- package/src/headers/20/node_v8.h +77 -0
- package/src/headers/20/node_v8_platform-inl.h +205 -0
- package/src/headers/20/node_version.h +109 -0
- package/src/headers/20/node_wasi.h +184 -0
- package/src/headers/20/node_wasm_web_api.h +55 -0
- package/src/headers/20/node_watchdog.h +154 -0
- package/src/headers/20/node_worker.h +151 -0
- package/src/headers/20/permission/child_process_permission.h +29 -0
- package/src/headers/20/permission/fs_permission.h +154 -0
- package/src/headers/20/permission/inspector_permission.h +29 -0
- package/src/headers/20/permission/permission.h +74 -0
- package/src/headers/20/permission/permission_base.h +53 -0
- package/src/headers/20/permission/worker_permission.h +29 -0
- package/src/headers/20/pipe_wrap.h +80 -0
- package/src/headers/20/req_wrap-inl.h +171 -0
- package/src/headers/20/req_wrap.h +77 -0
- package/src/headers/20/spawn_sync.h +242 -0
- package/src/headers/20/stream_base-inl.h +173 -0
- package/src/headers/20/stream_base.h +469 -0
- package/src/headers/20/stream_pipe.h +76 -0
- package/src/headers/20/stream_wrap.h +131 -0
- package/src/headers/20/string_bytes.h +120 -0
- package/src/headers/20/string_decoder-inl.h +37 -0
- package/src/headers/20/string_decoder.h +50 -0
- package/src/headers/20/string_search.h +638 -0
- package/src/headers/20/tcp_wrap.h +105 -0
- package/src/headers/20/threadpoolwork-inl.h +70 -0
- package/src/headers/20/timer_wrap-inl.h +32 -0
- package/src/headers/20/timer_wrap.h +85 -0
- package/src/headers/20/timers.h +70 -0
- package/src/headers/20/tracing/agent.h +195 -0
- package/src/headers/20/tracing/node_trace_buffer.h +83 -0
- package/src/headers/20/tracing/node_trace_writer.h +75 -0
- package/src/headers/20/tracing/trace_event.h +720 -0
- package/src/headers/20/tracing/trace_event_common.h +1109 -0
- package/src/headers/20/tracing/traced_value.h +70 -0
- package/src/headers/20/tty_wrap.h +65 -0
- package/src/headers/20/udp_wrap.h +227 -0
- package/src/headers/20/undici_version.h +6 -0
- package/src/headers/20/util-inl.h +623 -0
- package/src/headers/20/util.h +988 -0
- package/src/headers/20/v8-cppgc.h +245 -0
- package/src/headers/20/v8-fast-api-calls.h +957 -0
- package/dist/bindings/cws_darwin_arm64_node64.node +0 -0
- package/dist/bindings/cws_darwin_arm64_node72.node +0 -0
- package/dist/bindings/cws_darwin_arm64_node79.node +0 -0
- package/dist/bindings/cws_darwin_x64_node64.node +0 -0
- package/dist/bindings/cws_darwin_x64_node72.node +0 -0
- package/dist/bindings/cws_darwin_x64_node79.node +0 -0
- package/dist/bindings/cws_linux_x64_node64.node +0 -0
- package/dist/bindings/cws_linux_x64_node72.node +0 -0
- package/dist/bindings/cws_linux_x64_node79.node +0 -0
- package/dist/bindings/cws_win32_x64_node64.node +0 -0
- package/dist/bindings/cws_win32_x64_node72.node +0 -0
- package/dist/bindings/cws_win32_x64_node79.node +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#ifndef SRC_JS_STREAM_H_
|
|
2
|
+
#define SRC_JS_STREAM_H_
|
|
3
|
+
|
|
4
|
+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
5
|
+
|
|
6
|
+
#include "async_wrap.h"
|
|
7
|
+
#include "stream_base.h"
|
|
8
|
+
|
|
9
|
+
namespace node {
|
|
10
|
+
|
|
11
|
+
class Environment;
|
|
12
|
+
|
|
13
|
+
class JSStream : public AsyncWrap, public StreamBase {
|
|
14
|
+
public:
|
|
15
|
+
static void Initialize(v8::Local<v8::Object> target,
|
|
16
|
+
v8::Local<v8::Value> unused,
|
|
17
|
+
v8::Local<v8::Context> context,
|
|
18
|
+
void* priv);
|
|
19
|
+
|
|
20
|
+
bool IsAlive() override;
|
|
21
|
+
bool IsClosing() override;
|
|
22
|
+
int ReadStart() override;
|
|
23
|
+
int ReadStop() override;
|
|
24
|
+
|
|
25
|
+
int DoShutdown(ShutdownWrap* req_wrap) override;
|
|
26
|
+
int DoWrite(WriteWrap* w,
|
|
27
|
+
uv_buf_t* bufs,
|
|
28
|
+
size_t count,
|
|
29
|
+
uv_stream_t* send_handle) override;
|
|
30
|
+
|
|
31
|
+
SET_NO_MEMORY_INFO()
|
|
32
|
+
SET_MEMORY_INFO_NAME(JSStream)
|
|
33
|
+
SET_SELF_SIZE(JSStream)
|
|
34
|
+
|
|
35
|
+
protected:
|
|
36
|
+
JSStream(Environment* env, v8::Local<v8::Object> obj);
|
|
37
|
+
|
|
38
|
+
AsyncWrap* GetAsyncWrap() override;
|
|
39
|
+
|
|
40
|
+
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
41
|
+
static void ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
42
|
+
static void EmitEOF(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
43
|
+
|
|
44
|
+
template <class Wrap>
|
|
45
|
+
static void Finish(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
} // namespace node
|
|
49
|
+
|
|
50
|
+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
51
|
+
|
|
52
|
+
#endif // SRC_JS_STREAM_H_
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#ifndef SRC_JSON_PARSER_H_
|
|
2
|
+
#define SRC_JSON_PARSER_H_
|
|
3
|
+
|
|
4
|
+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
5
|
+
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <optional>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include "util.h"
|
|
10
|
+
#include "v8.h"
|
|
11
|
+
|
|
12
|
+
namespace node {
|
|
13
|
+
// This is intended to be used to get some top-level fields out of a JSON
|
|
14
|
+
// without having to spin up a full Node.js environment that unnecessarily
|
|
15
|
+
// complicates things.
|
|
16
|
+
class JSONParser {
|
|
17
|
+
public:
|
|
18
|
+
JSONParser();
|
|
19
|
+
~JSONParser() = default;
|
|
20
|
+
bool Parse(const std::string& content);
|
|
21
|
+
std::optional<std::string> GetTopLevelStringField(std::string_view field);
|
|
22
|
+
std::optional<bool> GetTopLevelBoolField(std::string_view field);
|
|
23
|
+
|
|
24
|
+
private:
|
|
25
|
+
// We might want a lighter-weight JSON parser for this use case. But for now
|
|
26
|
+
// using V8 is good enough.
|
|
27
|
+
RAIIIsolate isolate_;
|
|
28
|
+
v8::HandleScope handle_scope_;
|
|
29
|
+
v8::Global<v8::Context> context_;
|
|
30
|
+
v8::Context::Scope context_scope_;
|
|
31
|
+
v8::Global<v8::Object> content_;
|
|
32
|
+
bool parsed_ = false;
|
|
33
|
+
};
|
|
34
|
+
} // namespace node
|
|
35
|
+
|
|
36
|
+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
37
|
+
|
|
38
|
+
#endif // SRC_JSON_PARSER_H_
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#ifndef SRC_JSON_UTILS_H_
|
|
2
|
+
#define SRC_JSON_UTILS_H_
|
|
3
|
+
|
|
4
|
+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
5
|
+
|
|
6
|
+
#include <iomanip>
|
|
7
|
+
#include <limits>
|
|
8
|
+
#include <ostream>
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <string_view>
|
|
11
|
+
|
|
12
|
+
namespace node {
|
|
13
|
+
|
|
14
|
+
constexpr bool NeedsJsonEscape(std::string_view str) {
|
|
15
|
+
for (const char c : str) {
|
|
16
|
+
if (c == '\\' || c == '"' || c < 0x20) return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
std::string EscapeJsonChars(std::string_view str);
|
|
22
|
+
std::string Reindent(const std::string& str, int indentation);
|
|
23
|
+
|
|
24
|
+
// JSON compiler definitions.
|
|
25
|
+
class JSONWriter {
|
|
26
|
+
public:
|
|
27
|
+
JSONWriter(std::ostream& out, bool compact)
|
|
28
|
+
: out_(out), compact_(compact) {}
|
|
29
|
+
|
|
30
|
+
private:
|
|
31
|
+
inline void indent() { indent_ += 2; }
|
|
32
|
+
inline void deindent() { indent_ -= 2; }
|
|
33
|
+
inline void advance() {
|
|
34
|
+
if (compact_) return;
|
|
35
|
+
for (int i = 0; i < indent_; i++) out_ << ' ';
|
|
36
|
+
}
|
|
37
|
+
inline void write_one_space() {
|
|
38
|
+
if (compact_) return;
|
|
39
|
+
out_ << ' ';
|
|
40
|
+
}
|
|
41
|
+
inline void write_new_line() {
|
|
42
|
+
if (compact_) return;
|
|
43
|
+
out_ << '\n';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public:
|
|
47
|
+
inline void json_start() {
|
|
48
|
+
if (state_ == kAfterValue) out_ << ',';
|
|
49
|
+
write_new_line();
|
|
50
|
+
advance();
|
|
51
|
+
out_ << '{';
|
|
52
|
+
indent();
|
|
53
|
+
state_ = kObjectStart;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
inline void json_end() {
|
|
57
|
+
write_new_line();
|
|
58
|
+
deindent();
|
|
59
|
+
advance();
|
|
60
|
+
out_ << '}';
|
|
61
|
+
state_ = kAfterValue;
|
|
62
|
+
}
|
|
63
|
+
template <typename T>
|
|
64
|
+
inline void json_objectstart(T key) {
|
|
65
|
+
if (state_ == kAfterValue) out_ << ',';
|
|
66
|
+
write_new_line();
|
|
67
|
+
advance();
|
|
68
|
+
write_string(key);
|
|
69
|
+
out_ << ':';
|
|
70
|
+
write_one_space();
|
|
71
|
+
out_ << '{';
|
|
72
|
+
indent();
|
|
73
|
+
state_ = kObjectStart;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
template <typename T>
|
|
77
|
+
inline void json_arraystart(T key) {
|
|
78
|
+
if (state_ == kAfterValue) out_ << ',';
|
|
79
|
+
write_new_line();
|
|
80
|
+
advance();
|
|
81
|
+
write_string(key);
|
|
82
|
+
out_ << ':';
|
|
83
|
+
write_one_space();
|
|
84
|
+
out_ << '[';
|
|
85
|
+
indent();
|
|
86
|
+
state_ = kObjectStart;
|
|
87
|
+
}
|
|
88
|
+
inline void json_objectend() {
|
|
89
|
+
write_new_line();
|
|
90
|
+
deindent();
|
|
91
|
+
advance();
|
|
92
|
+
out_ << '}';
|
|
93
|
+
if (indent_ == 0) {
|
|
94
|
+
// Top-level object is complete, so end the line.
|
|
95
|
+
out_ << '\n';
|
|
96
|
+
}
|
|
97
|
+
state_ = kAfterValue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
inline void json_arrayend() {
|
|
101
|
+
write_new_line();
|
|
102
|
+
deindent();
|
|
103
|
+
advance();
|
|
104
|
+
out_ << ']';
|
|
105
|
+
state_ = kAfterValue;
|
|
106
|
+
}
|
|
107
|
+
template <typename T, typename U>
|
|
108
|
+
inline void json_keyvalue(const T& key, const U& value) {
|
|
109
|
+
if (state_ == kAfterValue) out_ << ',';
|
|
110
|
+
write_new_line();
|
|
111
|
+
advance();
|
|
112
|
+
write_string(key);
|
|
113
|
+
out_ << ':';
|
|
114
|
+
write_one_space();
|
|
115
|
+
write_value(value);
|
|
116
|
+
state_ = kAfterValue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
template <typename U>
|
|
120
|
+
inline void json_element(const U& value) {
|
|
121
|
+
if (state_ == kAfterValue) out_ << ',';
|
|
122
|
+
write_new_line();
|
|
123
|
+
advance();
|
|
124
|
+
write_value(value);
|
|
125
|
+
state_ = kAfterValue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
struct Null {}; // Usable as a JSON value.
|
|
129
|
+
|
|
130
|
+
struct ForeignJSON {
|
|
131
|
+
std::string as_string;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
private:
|
|
135
|
+
template <typename T,
|
|
136
|
+
typename test_for_number = typename std::
|
|
137
|
+
enable_if<std::numeric_limits<T>::is_specialized, bool>::type>
|
|
138
|
+
inline void write_value(T number) {
|
|
139
|
+
if constexpr (std::is_same<T, bool>::value)
|
|
140
|
+
out_ << (number ? "true" : "false");
|
|
141
|
+
else
|
|
142
|
+
out_ << number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
inline void write_value(Null null) { out_ << "null"; }
|
|
146
|
+
inline void write_value(std::string_view str) { write_string(str); }
|
|
147
|
+
|
|
148
|
+
inline void write_value(const ForeignJSON& json) {
|
|
149
|
+
out_ << Reindent(json.as_string, indent_);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
inline void write_string(std::string_view str) {
|
|
153
|
+
out_ << '"';
|
|
154
|
+
if (NeedsJsonEscape(str)) // only create temporary std::string if necessary
|
|
155
|
+
out_ << EscapeJsonChars(str);
|
|
156
|
+
else
|
|
157
|
+
out_ << str;
|
|
158
|
+
out_ << '"';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
enum JSONState { kObjectStart, kAfterValue };
|
|
162
|
+
std::ostream& out_;
|
|
163
|
+
bool compact_;
|
|
164
|
+
int indent_ = 0;
|
|
165
|
+
int state_ = kObjectStart;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
} // namespace node
|
|
169
|
+
|
|
170
|
+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
171
|
+
|
|
172
|
+
#endif // SRC_JSON_UTILS_H_
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
#ifndef SRC_MEMORY_TRACKER_INL_H_
|
|
2
|
+
#define SRC_MEMORY_TRACKER_INL_H_
|
|
3
|
+
|
|
4
|
+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
5
|
+
|
|
6
|
+
#include "memory_tracker.h"
|
|
7
|
+
#include "util-inl.h"
|
|
8
|
+
|
|
9
|
+
namespace node {
|
|
10
|
+
|
|
11
|
+
// Fallback edge_name if node_name is not available, or "" if edge_name
|
|
12
|
+
// is not available either.
|
|
13
|
+
inline const char* GetNodeName(const char* node_name, const char* edge_name) {
|
|
14
|
+
if (node_name != nullptr) {
|
|
15
|
+
return node_name;
|
|
16
|
+
}
|
|
17
|
+
if (edge_name != nullptr) {
|
|
18
|
+
return edge_name;
|
|
19
|
+
}
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class MemoryRetainerNode : public v8::EmbedderGraph::Node {
|
|
24
|
+
public:
|
|
25
|
+
inline MemoryRetainerNode(MemoryTracker* tracker,
|
|
26
|
+
const MemoryRetainer* retainer)
|
|
27
|
+
: retainer_(retainer) {
|
|
28
|
+
CHECK_NOT_NULL(retainer_);
|
|
29
|
+
v8::HandleScope handle_scope(tracker->isolate());
|
|
30
|
+
v8::Local<v8::Object> obj = retainer_->WrappedObject();
|
|
31
|
+
if (!obj.IsEmpty()) wrapper_node_ = tracker->graph()->V8Node(obj);
|
|
32
|
+
|
|
33
|
+
name_ = retainer_->MemoryInfoName();
|
|
34
|
+
size_ = retainer_->SelfSize();
|
|
35
|
+
detachedness_ = retainer_->GetDetachedness();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
inline MemoryRetainerNode(MemoryTracker* tracker,
|
|
39
|
+
const char* name,
|
|
40
|
+
size_t size,
|
|
41
|
+
bool is_root_node = false)
|
|
42
|
+
: retainer_(nullptr) {
|
|
43
|
+
name_ = name;
|
|
44
|
+
size_ = size;
|
|
45
|
+
is_root_node_ = is_root_node;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const char* Name() override { return name_; }
|
|
49
|
+
const char* NamePrefix() override { return "Node /"; }
|
|
50
|
+
size_t SizeInBytes() override { return size_; }
|
|
51
|
+
// TODO(addaleax): Merging this with the "official" WrapperNode() method
|
|
52
|
+
// seems to lose accuracy, e.g. SizeInBytes() is disregarded.
|
|
53
|
+
// Figure out whether to do anything about that.
|
|
54
|
+
Node* JSWrapperNode() { return wrapper_node_; }
|
|
55
|
+
|
|
56
|
+
bool IsRootNode() override {
|
|
57
|
+
if (retainer_ != nullptr) {
|
|
58
|
+
return retainer_->IsRootNode();
|
|
59
|
+
}
|
|
60
|
+
return is_root_node_;
|
|
61
|
+
}
|
|
62
|
+
v8::EmbedderGraph::Node::Detachedness GetDetachedness() override {
|
|
63
|
+
return detachedness_;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private:
|
|
67
|
+
friend class MemoryTracker;
|
|
68
|
+
|
|
69
|
+
// If retainer_ is not nullptr, then it must have a wrapper_node_,
|
|
70
|
+
// and we have
|
|
71
|
+
// name_ == retainer_->MemoryInfoName()
|
|
72
|
+
// size_ == retainer_->SelfSize()
|
|
73
|
+
// is_root_node_ == retainer_->IsRootNode()
|
|
74
|
+
const MemoryRetainer* retainer_;
|
|
75
|
+
Node* wrapper_node_ = nullptr;
|
|
76
|
+
|
|
77
|
+
// Otherwise (retainer == nullptr), we set these fields in an ad-hoc way
|
|
78
|
+
bool is_root_node_ = false;
|
|
79
|
+
const char* name_;
|
|
80
|
+
size_t size_ = 0;
|
|
81
|
+
v8::EmbedderGraph::Node::Detachedness detachedness_ =
|
|
82
|
+
v8::EmbedderGraph::Node::Detachedness::kUnknown;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
void MemoryTracker::TrackFieldWithSize(const char* edge_name,
|
|
86
|
+
size_t size,
|
|
87
|
+
const char* node_name) {
|
|
88
|
+
if (size > 0) AddNode(GetNodeName(node_name, edge_name), size, edge_name);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void MemoryTracker::TrackInlineFieldWithSize(const char* edge_name,
|
|
92
|
+
size_t size,
|
|
93
|
+
const char* node_name) {
|
|
94
|
+
if (size > 0) AddNode(GetNodeName(node_name, edge_name), size, edge_name);
|
|
95
|
+
CHECK(CurrentNode());
|
|
96
|
+
CurrentNode()->size_ -= size;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
100
|
+
const MemoryRetainer& value,
|
|
101
|
+
const char* node_name) {
|
|
102
|
+
TrackField(edge_name, &value);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
106
|
+
const MemoryRetainer* value,
|
|
107
|
+
const char* node_name) {
|
|
108
|
+
if (value == nullptr) return;
|
|
109
|
+
auto it = seen_.find(value);
|
|
110
|
+
if (it != seen_.end()) {
|
|
111
|
+
graph_->AddEdge(CurrentNode(), it->second, edge_name);
|
|
112
|
+
} else {
|
|
113
|
+
Track(value, edge_name);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
template <typename T, typename D>
|
|
118
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
119
|
+
const std::unique_ptr<T, D>& value,
|
|
120
|
+
const char* node_name) {
|
|
121
|
+
if (value.get() == nullptr) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
TrackField(edge_name, value.get(), node_name);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
template <typename T>
|
|
128
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
129
|
+
const std::shared_ptr<T>& value,
|
|
130
|
+
const char* node_name) {
|
|
131
|
+
if (value.get() == nullptr) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
TrackField(edge_name, value.get(), node_name);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
template <typename T, bool kIsWeak>
|
|
138
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
139
|
+
const BaseObjectPtrImpl<T, kIsWeak>& value,
|
|
140
|
+
const char* node_name) {
|
|
141
|
+
if (value.get() == nullptr || kIsWeak) return;
|
|
142
|
+
TrackField(edge_name, value.get(), node_name);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
template <typename T, typename Iterator>
|
|
146
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
147
|
+
const T& value,
|
|
148
|
+
const char* node_name,
|
|
149
|
+
const char* element_name,
|
|
150
|
+
bool subtract_from_self) {
|
|
151
|
+
// If the container is empty, the size has been accounted into the parent's
|
|
152
|
+
// self size
|
|
153
|
+
if (value.begin() == value.end()) return;
|
|
154
|
+
// Fall back to edge name if node names are not provided
|
|
155
|
+
if (CurrentNode() != nullptr && subtract_from_self) {
|
|
156
|
+
// Shift the self size of this container out to a separate node
|
|
157
|
+
CurrentNode()->size_ -= sizeof(T);
|
|
158
|
+
}
|
|
159
|
+
PushNode(GetNodeName(node_name, edge_name), sizeof(T), edge_name);
|
|
160
|
+
for (Iterator it = value.begin(); it != value.end(); ++it) {
|
|
161
|
+
// Use nullptr as edge names so the elements appear as indexed properties
|
|
162
|
+
TrackField(nullptr, *it, element_name);
|
|
163
|
+
}
|
|
164
|
+
PopNode();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
template <typename T>
|
|
168
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
169
|
+
const std::queue<T>& value,
|
|
170
|
+
const char* node_name,
|
|
171
|
+
const char* element_name) {
|
|
172
|
+
struct ContainerGetter : public std::queue<T> {
|
|
173
|
+
static const typename std::queue<T>::container_type& Get(
|
|
174
|
+
const std::queue<T>& value) {
|
|
175
|
+
return value.*&ContainerGetter::c;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const auto& container = ContainerGetter::Get(value);
|
|
180
|
+
TrackField(edge_name, container, node_name, element_name);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
template <typename T, typename test_for_number, typename dummy>
|
|
184
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
185
|
+
const T& value,
|
|
186
|
+
const char* node_name) {
|
|
187
|
+
// For numbers, creating new nodes is not worth the overhead.
|
|
188
|
+
CurrentNode()->size_ += sizeof(T);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
template <typename T, typename U>
|
|
192
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
193
|
+
const std::pair<T, U>& value,
|
|
194
|
+
const char* node_name) {
|
|
195
|
+
PushNode(node_name == nullptr ? "pair" : node_name,
|
|
196
|
+
sizeof(const std::pair<T, U>),
|
|
197
|
+
edge_name);
|
|
198
|
+
// TODO(joyeecheung): special case if one of these is a number type
|
|
199
|
+
// that meets the test_for_number trait so that their sizes don't get
|
|
200
|
+
// merged into the pair node
|
|
201
|
+
TrackField("first", value.first);
|
|
202
|
+
TrackField("second", value.second);
|
|
203
|
+
PopNode();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
template <typename T>
|
|
207
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
208
|
+
const std::basic_string<T>& value,
|
|
209
|
+
const char* node_name) {
|
|
210
|
+
TrackFieldWithSize(edge_name, value.size() * sizeof(T), "std::basic_string");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
template <typename T>
|
|
214
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
215
|
+
const v8::Eternal<T>& value,
|
|
216
|
+
const char* node_name) {
|
|
217
|
+
TrackField(edge_name, value.Get(isolate_));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
template <typename T>
|
|
221
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
222
|
+
const v8::PersistentBase<T>& value,
|
|
223
|
+
const char* node_name) {
|
|
224
|
+
if (value.IsWeak()) return;
|
|
225
|
+
TrackField(edge_name, value.Get(isolate_));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
template <typename T>
|
|
229
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
230
|
+
const v8::Local<T>& value,
|
|
231
|
+
const char* node_name) {
|
|
232
|
+
if (!value.IsEmpty())
|
|
233
|
+
graph_->AddEdge(CurrentNode(), graph_->V8Node(value), edge_name);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
template <typename T>
|
|
237
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
238
|
+
const MallocedBuffer<T>& value,
|
|
239
|
+
const char* node_name) {
|
|
240
|
+
TrackFieldWithSize(edge_name, value.size, "MallocedBuffer");
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
void MemoryTracker::TrackField(const char* edge_name,
|
|
244
|
+
const v8::BackingStore* value,
|
|
245
|
+
const char* node_name) {
|
|
246
|
+
TrackFieldWithSize(edge_name, value->ByteLength(), "BackingStore");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
void MemoryTracker::TrackField(const char* name,
|
|
250
|
+
const uv_buf_t& value,
|
|
251
|
+
const char* node_name) {
|
|
252
|
+
TrackFieldWithSize(name, value.len, "uv_buf_t");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
void MemoryTracker::TrackField(const char* name,
|
|
256
|
+
const uv_timer_t& value,
|
|
257
|
+
const char* node_name) {
|
|
258
|
+
TrackFieldWithSize(name, sizeof(value), "uv_timer_t");
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
void MemoryTracker::TrackField(const char* name,
|
|
262
|
+
const uv_async_t& value,
|
|
263
|
+
const char* node_name) {
|
|
264
|
+
TrackFieldWithSize(name, sizeof(value), "uv_async_t");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
void MemoryTracker::TrackInlineField(const char* name,
|
|
268
|
+
const uv_async_t& value,
|
|
269
|
+
const char* node_name) {
|
|
270
|
+
TrackInlineFieldWithSize(name, sizeof(value), "uv_async_t");
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
void MemoryTracker::Track(const MemoryRetainer* retainer,
|
|
274
|
+
const char* edge_name) {
|
|
275
|
+
v8::HandleScope handle_scope(isolate_);
|
|
276
|
+
auto it = seen_.find(retainer);
|
|
277
|
+
if (it != seen_.end()) {
|
|
278
|
+
if (CurrentNode() != nullptr) {
|
|
279
|
+
graph_->AddEdge(CurrentNode(), it->second, edge_name);
|
|
280
|
+
}
|
|
281
|
+
return; // It has already been tracked, no need to call MemoryInfo again
|
|
282
|
+
}
|
|
283
|
+
MemoryRetainerNode* n = PushNode(retainer, edge_name);
|
|
284
|
+
retainer->MemoryInfo(this);
|
|
285
|
+
CHECK_EQ(CurrentNode(), n);
|
|
286
|
+
CHECK_NE(n->size_, 0);
|
|
287
|
+
PopNode();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
void MemoryTracker::TrackInlineField(const MemoryRetainer* retainer,
|
|
291
|
+
const char* edge_name) {
|
|
292
|
+
Track(retainer, edge_name);
|
|
293
|
+
CHECK(CurrentNode());
|
|
294
|
+
CurrentNode()->size_ -= retainer->SelfSize();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
MemoryRetainerNode* MemoryTracker::CurrentNode() const {
|
|
298
|
+
if (node_stack_.empty()) return nullptr;
|
|
299
|
+
return node_stack_.top();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
MemoryRetainerNode* MemoryTracker::AddNode(const MemoryRetainer* retainer,
|
|
303
|
+
const char* edge_name) {
|
|
304
|
+
auto it = seen_.find(retainer);
|
|
305
|
+
if (it != seen_.end()) {
|
|
306
|
+
return it->second;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
MemoryRetainerNode* n = new MemoryRetainerNode(this, retainer);
|
|
310
|
+
graph_->AddNode(std::unique_ptr<v8::EmbedderGraph::Node>(n));
|
|
311
|
+
seen_[retainer] = n;
|
|
312
|
+
if (CurrentNode() != nullptr) graph_->AddEdge(CurrentNode(), n, edge_name);
|
|
313
|
+
|
|
314
|
+
if (n->JSWrapperNode() != nullptr) {
|
|
315
|
+
graph_->AddEdge(n, n->JSWrapperNode(), "native_to_javascript");
|
|
316
|
+
graph_->AddEdge(n->JSWrapperNode(), n, "javascript_to_native");
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return n;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
MemoryRetainerNode* MemoryTracker::AddNode(const char* node_name,
|
|
323
|
+
size_t size,
|
|
324
|
+
const char* edge_name) {
|
|
325
|
+
MemoryRetainerNode* n = new MemoryRetainerNode(this, node_name, size);
|
|
326
|
+
graph_->AddNode(std::unique_ptr<v8::EmbedderGraph::Node>(n));
|
|
327
|
+
|
|
328
|
+
if (CurrentNode() != nullptr) graph_->AddEdge(CurrentNode(), n, edge_name);
|
|
329
|
+
|
|
330
|
+
return n;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
MemoryRetainerNode* MemoryTracker::PushNode(const MemoryRetainer* retainer,
|
|
334
|
+
const char* edge_name) {
|
|
335
|
+
MemoryRetainerNode* n = AddNode(retainer, edge_name);
|
|
336
|
+
node_stack_.push(n);
|
|
337
|
+
return n;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
MemoryRetainerNode* MemoryTracker::PushNode(const char* node_name,
|
|
341
|
+
size_t size,
|
|
342
|
+
const char* edge_name) {
|
|
343
|
+
MemoryRetainerNode* n = AddNode(node_name, size, edge_name);
|
|
344
|
+
node_stack_.push(n);
|
|
345
|
+
return n;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
void MemoryTracker::PopNode() {
|
|
349
|
+
node_stack_.pop();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
} // namespace node
|
|
353
|
+
|
|
354
|
+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
355
|
+
|
|
356
|
+
#endif // SRC_MEMORY_TRACKER_INL_H_
|