From 3e2ea85f5a4d86e8a4a3570fa254e45358365f40 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 21:06:04 +0200 Subject: [PATCH] Replace NativeString heap allocations with thread-local pool allocator (#1263) * Initial plan * Update NativeString callers to use new NativeStringContext parameter Add NativeStringContext nativeStringContext; as the first local variable in each function containing NativeString constructions, and pass it as the first argument to each NativeString constructor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: uNetworkingAB <110806833+uNetworkingAB@users.noreply.github.com> * Add NativeStringContext and update NativeString to use pool allocation in Utilities.h Agent-Logs-Url: https://github.com/uNetworking/uWebSockets.js/sessions/0a6be420-47f1-4fb3-a5d5-55f6d09eb1b5 Co-authored-by: uNetworkingAB <110806833+uNetworkingAB@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: uNetworkingAB <110806833+uNetworkingAB@users.noreply.github.com> --- src/AppWrapper.h | 47 +++++++++++++++++++------------- src/HttpRequestWrapper.h | 9 ++++--- src/HttpResponseWrapper.h | 24 ++++++++++------- src/Utilities.h | 30 ++++++++++++--------- src/WebSocketWrapper.h | 32 ++++++++++++++-------- src/addon.cpp | 57 ++++++++++++++++++++++++--------------- 6 files changed, 124 insertions(+), 75 deletions(-) diff --git a/src/AppWrapper.h b/src/AppWrapper.h index db21860d..c7a0320e 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -37,7 +37,8 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { /* This one is default constructed with defaults */ typename APP::template WebSocketBehavior behavior = {}; - NativeString pattern(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString pattern(nativeStringContext, args.GetIsolate(), args[0]); if (pattern.isInvalid(args)) { return; } @@ -313,8 +314,9 @@ template void uWS_App_get(F f, const FunctionCallbackInfo &args) { APP *app = (APP *) args.This()->GetAlignedPointerFromInternalField(0); + NativeStringContext nativeStringContext; /* Pattern */ - NativeString pattern(args.GetIsolate(), args[0]); + NativeString pattern(nativeStringContext, args.GetIsolate(), args[0]); if (pattern.isInvalid(args)) { return; } @@ -328,7 +330,7 @@ void uWS_App_get(F f, const FunctionCallbackInfo &args) { /* If the handler is String */ if (args[1]->IsArrayBuffer()) { - NativeString constantString(args.GetIsolate(), args[1]); + NativeString constantString(nativeStringContext, args.GetIsolate(), args[1]); if (constantString.isInvalid(args)) { return; } @@ -513,7 +515,8 @@ void uWS_App_listen_unix(const FunctionCallbackInfo &args) { /* Path is last */ std::string path; - NativeString h(isolate, args[args.Length() - 1]); + NativeStringContext nativeStringContext; + NativeString h(nativeStringContext, isolate, args[args.Length() - 1]); if (h.isInvalid(args)) { return; } @@ -545,8 +548,9 @@ void uWS_App_listen(const FunctionCallbackInfo &args) { /* Host is first, if present */ std::string host; + NativeStringContext nativeStringContext; if (!args[0]->IsNumber()) { - NativeString h(isolate, args[0]); + NativeString h(nativeStringContext, isolate, args[0]); if (h.isInvalid(args)) { return; } @@ -605,7 +609,8 @@ void uWS_App_domain(const FunctionCallbackInfo &args) { return; } - NativeString serverName(isolate, args[0]); + NativeStringContext nativeStringContext; + NativeString serverName(nativeStringContext, isolate, args[0]); if (serverName.isInvalid(args)) { return; } @@ -626,12 +631,13 @@ void uWS_App_publish(const FunctionCallbackInfo &args) { return; } - NativeString topic(isolate, args[0]); + NativeStringContext nativeStringContext; + NativeString topic(nativeStringContext, isolate, args[0]); if (topic.isInvalid(args)) { return; } - NativeString message(isolate, args[1]); + NativeString message(nativeStringContext, isolate, args[1]); if (message.isInvalid(args)) { return; } @@ -652,7 +658,8 @@ void uWS_App_numSubscribers(const FunctionCallbackInfo &args) { return; } - NativeString topic(isolate, args[0]); + NativeStringContext nativeStringContext; + NativeString topic(nativeStringContext, isolate, args[0]); if (topic.isInvalid(args)) { return; } @@ -675,8 +682,9 @@ std::pair readOptionsObject(const FunctionCallb Local optionsObject = Local::Cast(args[index]); + NativeStringContext nativeStringContext; /* Key file name */ - NativeString keyFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "key_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + NativeString keyFileNameValue(nativeStringContext, isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "key_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (keyFileNameValue.isInvalid(args)) { return {}; } @@ -686,7 +694,7 @@ std::pair readOptionsObject(const FunctionCallb } /* Cert file name */ - NativeString certFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "cert_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + NativeString certFileNameValue(nativeStringContext, isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "cert_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (certFileNameValue.isInvalid(args)) { return {}; } @@ -696,7 +704,7 @@ std::pair readOptionsObject(const FunctionCallb } /* Passphrase */ - NativeString passphraseValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "passphrase", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + NativeString passphraseValue(nativeStringContext, isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "passphrase", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (passphraseValue.isInvalid(args)) { return {}; } @@ -706,7 +714,7 @@ std::pair readOptionsObject(const FunctionCallb } /* DH params file name */ - NativeString dhParamsFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "dh_params_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + NativeString dhParamsFileNameValue(nativeStringContext, isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "dh_params_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (dhParamsFileNameValue.isInvalid(args)) { return {}; } @@ -716,7 +724,7 @@ std::pair readOptionsObject(const FunctionCallb } /* CA file name */ - NativeString caFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ca_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + NativeString caFileNameValue(nativeStringContext, isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ca_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (caFileNameValue.isInvalid(args)) { return {}; } @@ -729,7 +737,7 @@ std::pair readOptionsObject(const FunctionCallb options.ssl_prefer_low_memory_usage = optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ssl_prefer_low_memory_usage", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()->BooleanValue(isolate); /* ssl_ciphers */ - NativeString sslCiphersValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ssl_ciphers", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); + NativeString sslCiphersValue(nativeStringContext, isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ssl_ciphers", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (sslCiphersValue.isInvalid(args)) { return {}; } @@ -824,7 +832,8 @@ void uWS_App_addServerName(const FunctionCallbackInfo &args) { APP *app = (APP *) args.This()->GetAlignedPointerFromInternalField(0); Isolate *isolate = args.GetIsolate(); - NativeString hostnamePatternValue(isolate, args[0]); + NativeStringContext nativeStringContext; + NativeString hostnamePatternValue(nativeStringContext, isolate, args[0]); if (hostnamePatternValue.isInvalid(args)) { return; } @@ -848,7 +857,8 @@ void uWS_App_removeServerName(const FunctionCallbackInfo &args) { APP *app = (APP *) args.This()->GetAlignedPointerFromInternalField(0); Isolate *isolate = args.GetIsolate(); - NativeString hostnamePatternValue(isolate, args[0]); + NativeStringContext nativeStringContext; + NativeString hostnamePatternValue(nativeStringContext, isolate, args[0]); if (hostnamePatternValue.isInvalid(args)) { return; } @@ -930,8 +940,9 @@ void uWS_App(const FunctionCallbackInfo &args) { APP *app = (APP *) args.This()->GetAlignedPointerFromInternalField(0); + NativeStringContext nativeStringContext; /* Pattern */ - NativeString pattern(args.GetIsolate(), args[0]); + NativeString pattern(nativeStringContext, args.GetIsolate(), args[0]); if (pattern.isInvalid(args)) { return; } diff --git a/src/HttpRequestWrapper.h b/src/HttpRequestWrapper.h index 265c5a50..30dadfe2 100644 --- a/src/HttpRequestWrapper.h +++ b/src/HttpRequestWrapper.h @@ -62,6 +62,7 @@ struct HttpRequestWrapper { template static void req_getParameter(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *req = getHttpRequest(args); if (req) { @@ -71,7 +72,7 @@ struct HttpRequestWrapper { int index = args[0]->Uint32Value(isolate->GetCurrentContext()).ToChecked(); parameter = req->getParameter(index); } else { - NativeString data(args.GetIsolate(), args[0]); + NativeString data(nativeStringContext, args.GetIsolate(), args[0]); if (data.isInvalid(args)) { return; } @@ -98,9 +99,10 @@ struct HttpRequestWrapper { template static void req_getHeader(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *req = getHttpRequest(args); if (req) { - NativeString data(args.GetIsolate(), args[0]); + NativeString data(nativeStringContext, args.GetIsolate(), args[0]); if (data.isInvalid(args)) { return; } @@ -152,13 +154,14 @@ struct HttpRequestWrapper { template static void req_getQuery(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *req = getHttpRequest(args); if (req) { std::string_view query; /* Do we have a key argument? */ if (args.Length() == 1) { - NativeString keyString(isolate, args[0]); + NativeString keyString(nativeStringContext, isolate, args[0]); if (keyString.isInvalid(args)) { return; } diff --git a/src/HttpResponseWrapper.h b/src/HttpResponseWrapper.h index 65a52803..c25f62ff 100644 --- a/src/HttpResponseWrapper.h +++ b/src/HttpResponseWrapper.h @@ -369,7 +369,8 @@ struct HttpResponseWrapper { static void res_writeStatus(const FunctionCallbackInfo &args) { auto *res = getHttpResponse(args); if (res) { - NativeString data(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString data(nativeStringContext, args.GetIsolate(), args[0]); if (data.isInvalid(args)) { return; } @@ -409,7 +410,8 @@ struct HttpResponseWrapper { static void res_end(const FunctionCallbackInfo &args) { auto *res = getHttpResponse(args); if (res) { - NativeString data(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString data(nativeStringContext, args.GetIsolate(), args[0]); if (data.isInvalid(args)) { return; } @@ -432,9 +434,10 @@ struct HttpResponseWrapper { template static void res_tryEnd(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *res = getHttpResponse(args); if (res) { - NativeString data(args.GetIsolate(), args[0]); + NativeString data(nativeStringContext, args.GetIsolate(), args[0]); if (data.isInvalid(args)) { return; } @@ -465,9 +468,10 @@ struct HttpResponseWrapper { template static void res_write(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *res = getHttpResponse(args); if (res) { - NativeString data(args.GetIsolate(), args[0]); + NativeString data(nativeStringContext, args.GetIsolate(), args[0]); if (data.isInvalid(args)) { return; } @@ -482,13 +486,14 @@ struct HttpResponseWrapper { template static void res_writeHeader(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *res = getHttpResponse(args); if (res) { - NativeString header(args.GetIsolate(), args[0]); + NativeString header(nativeStringContext, args.GetIsolate(), args[0]); if (header.isInvalid(args)) { return; } - NativeString value(args.GetIsolate(), args[1]); + NativeString value(nativeStringContext, args.GetIsolate(), args[1]); if (value.isInvalid(args)) { return; } @@ -521,6 +526,7 @@ struct HttpResponseWrapper { template static void res_upgrade(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *res = getHttpResponse(args); if (res) { /* We require exactly 5 arguments */ @@ -528,17 +534,17 @@ struct HttpResponseWrapper { return; } - NativeString secWebSocketKey(args.GetIsolate(), args[1]); + NativeString secWebSocketKey(nativeStringContext, args.GetIsolate(), args[1]); if (secWebSocketKey.isInvalid(args)) { return; } - NativeString secWebSocketProtocol(args.GetIsolate(), args[2]); + NativeString secWebSocketProtocol(nativeStringContext, args.GetIsolate(), args[2]); if (secWebSocketProtocol.isInvalid(args)) { return; } - NativeString secWebSocketExtensions(args.GetIsolate(), args[3]); + NativeString secWebSocketExtensions(nativeStringContext, args.GetIsolate(), args[3]); if (secWebSocketExtensions.isInvalid(args)) { return; } diff --git a/src/Utilities.h b/src/Utilities.h index 6a58d6cb..0e5c9e8e 100644 --- a/src/Utilities.h +++ b/src/Utilities.h @@ -21,6 +21,7 @@ #include #include #include +#include using namespace v8; /* Unfortunately we _have_ to depend on Node.js crap */ @@ -118,13 +119,26 @@ struct Callback { } }; +class NativeStringContext { + inline static thread_local std::vector pool = std::vector(8 * 1024 * 1024); + size_t pool_offset = 0; +public: + char *alloc(size_t size) { + if (pool_offset + size > pool.size()) { + pool.resize(pool_offset + size); + } + char *ptr = pool.data() + pool_offset; + pool_offset += size; + return ptr; + } +}; + class NativeString { char *data; size_t length; - bool strAllocated = false; bool invalid = false; public: - NativeString(Isolate *isolate, const Local &value) { + NativeString(NativeStringContext &ctx, Isolate *isolate, const Local &value) { if (value->IsUndefined()) { data = nullptr; length = 0; @@ -138,15 +152,13 @@ public: data = (char *) strView.data8(); } else { // utf16: copy and convert to utf8 - strAllocated = true; length = string->Utf8LengthV2(isolate); - data = new char[length]; + data = ctx.alloc(length); string->WriteUtf8V2(isolate, data, length); } #else // Fallback Node.js < 24 - strAllocated = true; length = string->Utf8Length(isolate); - data = new char[length]; + data = ctx.alloc(length); string->WriteUtf8(isolate, data, length, nullptr, String::WriteOptions::NO_NULL_TERMINATION); #endif } else if (value->IsArrayBufferView()) { /* DataView or TypedArray */ @@ -179,12 +191,6 @@ public: std::string_view getString() { return {data, length}; } - - ~NativeString() { - if (strAllocated) { - delete[] data; - } - } }; // Utility function to extract raw certificate data diff --git a/src/WebSocketWrapper.h b/src/WebSocketWrapper.h index 0d40583a..2a25c0c3 100644 --- a/src/WebSocketWrapper.h +++ b/src/WebSocketWrapper.h @@ -50,9 +50,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_subscribe(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString topic(isolate, args[0]); + NativeString topic(nativeStringContext, isolate, args[0]); if (topic.isInvalid(args)) { return; } @@ -66,9 +67,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_unsubscribe(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString topic(isolate, args[0]); + NativeString topic(nativeStringContext, isolate, args[0]); if (topic.isInvalid(args)) { return; } @@ -82,17 +84,18 @@ struct WebSocketWrapper { template static void uWS_WebSocket_publish(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { if (missingArguments(2, args)) { return; } - NativeString topic(isolate, args[0]); + NativeString topic(nativeStringContext, isolate, args[0]); if (topic.isInvalid(args)) { return; } - NativeString message(isolate, args[1]); + NativeString message(nativeStringContext, isolate, args[1]); if (message.isInvalid(args)) { return; } @@ -119,6 +122,7 @@ struct WebSocketWrapper { template static void uWS_WebSocket_end(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { int code = 0; @@ -126,7 +130,7 @@ struct WebSocketWrapper { code = args[0]->Uint32Value(isolate->GetCurrentContext()).ToChecked(); } - NativeString message(args.GetIsolate(), args[1]); + NativeString message(nativeStringContext, args.GetIsolate(), args[1]); if (message.isInvalid(args)) { return; } @@ -186,9 +190,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_sendFirstFragment(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString message(args.GetIsolate(), args[0]); + NativeString message(nativeStringContext, args.GetIsolate(), args[0]); if (message.isInvalid(args)) { return; } @@ -203,9 +208,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_sendFragment(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString message(args.GetIsolate(), args[0]); + NativeString message(nativeStringContext, args.GetIsolate(), args[0]); if (message.isInvalid(args)) { return; } @@ -220,9 +226,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_sendLastFragment(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString message(args.GetIsolate(), args[0]); + NativeString message(nativeStringContext, args.GetIsolate(), args[0]); if (message.isInvalid(args)) { return; } @@ -237,9 +244,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_send(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString message(args.GetIsolate(), args[0]); + NativeString message(nativeStringContext, args.GetIsolate(), args[0]); if (message.isInvalid(args)) { return; } @@ -254,9 +262,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_isSubscribed(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString topic(args.GetIsolate(), args[0]); + NativeString topic(nativeStringContext, args.GetIsolate(), args[0]); if (topic.isInvalid(args)) { return; } @@ -271,9 +280,10 @@ struct WebSocketWrapper { template static void uWS_WebSocket_ping(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); + NativeStringContext nativeStringContext; auto *ws = getWebSocket(args); if (ws) { - NativeString message(args.GetIsolate(), args[0]); + NativeString message(nativeStringContext, args.GetIsolate(), args[0]); if (message.isInvalid(args)) { return; } diff --git a/src/addon.cpp b/src/addon.cpp index f5fca5c6..b9bf88d2 100644 --- a/src/addon.cpp +++ b/src/addon.cpp @@ -46,14 +46,15 @@ void uWS_getParts(const FunctionCallbackInfo &args) { /* Because we mutate the strings, it is important that we get mutable input like * ArrayBuffer or Buffer, not String! */ + NativeStringContext nativeStringContext; Isolate *isolate = args.GetIsolate(); - NativeString body(args.GetIsolate(), args[0]); + NativeString body(nativeStringContext, args.GetIsolate(), args[0]); if (body.isInvalid(args)) { return; } - NativeString contentType(args.GetIsolate(), args[1]); + NativeString contentType(nativeStringContext, args.GetIsolate(), args[1]); if (contentType.isInvalid(args)) { return; } @@ -149,7 +150,8 @@ void uWS_clearTimeout(const FunctionCallbackInfo &args) { /* Pass various undocumented configs */ void uWS_cfg(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } @@ -183,12 +185,13 @@ std::mutex kvMutex; // getString(key, collection) void uWS_getString(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } - NativeString collection(args.GetIsolate(), args[1]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[1]); if (collection.isInvalid(args)) { return; } @@ -199,16 +202,17 @@ void uWS_getString(const FunctionCallbackInfo &args) { } void uWS_setString(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } - NativeString value(args.GetIsolate(), args[1]); + NativeString value(nativeStringContext, args.GetIsolate(), args[1]); if (value.isInvalid(args)) { return; } - NativeString collection(args.GetIsolate(), args[2]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[2]); if (collection.isInvalid(args)) { return; } @@ -217,12 +221,13 @@ void uWS_setString(const FunctionCallbackInfo &args) { } void uWS_getInteger(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } - NativeString collection(args.GetIsolate(), args[1]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[1]); if (collection.isInvalid(args)) { return; } @@ -233,14 +238,15 @@ void uWS_getInteger(const FunctionCallbackInfo &args) { } void uWS_setInteger(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } uint32_t value = Local::Cast(args[1])->Value(); - NativeString collection(args.GetIsolate(), args[2]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[2]); if (collection.isInvalid(args)) { return; } @@ -249,14 +255,15 @@ void uWS_setInteger(const FunctionCallbackInfo &args) { } void uWS_incInteger(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } uint32_t change = Local::Cast(args[1])->Value(); - NativeString collection(args.GetIsolate(), args[2]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[2]); if (collection.isInvalid(args)) { return; } @@ -269,7 +276,8 @@ void uWS_incInteger(const FunctionCallbackInfo &args) { /* This one will spike memory usage for large stores */ void uWS_getStringKeys(const FunctionCallbackInfo &args) { - NativeString collection(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString collection(nativeStringContext, args.GetIsolate(), args[0]); if (collection.isInvalid(args)) { return; } @@ -287,7 +295,8 @@ void uWS_getStringKeys(const FunctionCallbackInfo &args) { void uWS_getIntegerKeys(const FunctionCallbackInfo &args) { - NativeString collection(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString collection(nativeStringContext, args.GetIsolate(), args[0]); if (collection.isInvalid(args)) { return; } @@ -305,12 +314,13 @@ void uWS_getIntegerKeys(const FunctionCallbackInfo &args) { void uWS_deleteString(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } - NativeString collection(args.GetIsolate(), args[1]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[1]); if (collection.isInvalid(args)) { return; } @@ -322,12 +332,13 @@ void uWS_deleteString(const FunctionCallbackInfo &args) { void uWS_deleteInteger(const FunctionCallbackInfo &args) { - NativeString key(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString key(nativeStringContext, args.GetIsolate(), args[0]); if (key.isInvalid(args)) { return; } - NativeString collection(args.GetIsolate(), args[1]); + NativeString collection(nativeStringContext, args.GetIsolate(), args[1]); if (collection.isInvalid(args)) { return; } @@ -339,7 +350,8 @@ void uWS_deleteInteger(const FunctionCallbackInfo &args) { void uWS_deleteStringCollection(const FunctionCallbackInfo &args) { - NativeString collection(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString collection(nativeStringContext, args.GetIsolate(), args[0]); if (collection.isInvalid(args)) { return; } @@ -351,7 +363,8 @@ void uWS_deleteStringCollection(const FunctionCallbackInfo &args) { void uWS_deleteIntegerCollection(const FunctionCallbackInfo &args) { - NativeString collection(args.GetIsolate(), args[0]); + NativeStringContext nativeStringContext; + NativeString collection(nativeStringContext, args.GetIsolate(), args[0]); if (collection.isInvalid(args)) { return; }