From a8b24ef5ed7b6cd3a8a22fd7dd35ed013dad0def Mon Sep 17 00:00:00 2001 From: Iain Ireland Date: Tue, 29 Apr 2025 18:44:10 +0000 Subject: [PATCH] Bug 1963431: Add JS_StringifyWithLengthHint r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D247145 --- js/public/JSON.h | 7 +++++++ js/src/jsapi.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/js/public/JSON.h b/js/public/JSON.h index feef53f755e8..2cf546e9c8da 100644 --- a/js/public/JSON.h +++ b/js/public/JSON.h @@ -26,12 +26,19 @@ using JSONWriteCallback = bool (*)(const char16_t* buf, uint32_t len, * * In cases where JSON.stringify would return undefined, this function calls * |callback| with the string "null". + * + * If a length hint is passed, space will be reserved for at least that many + * characters. */ extern JS_PUBLIC_API bool JS_Stringify(JSContext* cx, JS::MutableHandle value, JS::Handle replacer, JS::Handle space, JSONWriteCallback callback, void* data); +extern JS_PUBLIC_API bool JS_StringifyWithLengthHint( + JSContext* cx, JS::MutableHandle value, + JS::Handle replacer, JS::Handle space, + JSONWriteCallback callback, void* data, size_t lengthHint); namespace JS { diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index dc589a8d6a9a..415b611d5e69 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3665,6 +3665,15 @@ JS_PUBLIC_API bool JS::PropertySpecNameEqualsId(JSPropertySpec::Name name, JS_PUBLIC_API bool JS_Stringify(JSContext* cx, MutableHandleValue vp, HandleObject replacer, HandleValue space, JSONWriteCallback callback, void* data) { + return JS_StringifyWithLengthHint(cx, vp, replacer, space, callback, data, 0); +} + +JS_PUBLIC_API bool JS_StringifyWithLengthHint(JSContext* cx, + MutableHandleValue vp, + HandleObject replacer, + HandleValue space, + JSONWriteCallback callback, + void* data, size_t lengthHint) { AssertHeapIsIdle(); CHECK_THREAD(cx); cx->check(replacer, space); @@ -3672,6 +3681,9 @@ JS_PUBLIC_API bool JS_Stringify(JSContext* cx, MutableHandleValue vp, if (!sb.ensureTwoByteChars()) { return false; } + if (lengthHint && !sb.reserve(lengthHint)) { + return false; + } if (!Stringify(cx, vp, replacer, space, sb, StringifyBehavior::Normal)) { return false; }