From 2d4dbf64944bd27b9e02e48c58f5240b56b76345 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Sat, 1 May 2021 12:10:14 +0000 Subject: [PATCH] Bug 1708719 - Move string functions from jsapi.h to public/String.h r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D113992 --- js/public/String.h | 292 +++++++++++++++++++++++++++++++++++++++++++++ js/src/jsapi.h | 289 +------------------------------------------- 2 files changed, 293 insertions(+), 288 deletions(-) diff --git a/js/public/String.h b/js/public/String.h index ba02539ed0ea..de4d4dfd099e 100644 --- a/js/public/String.h +++ b/js/public/String.h @@ -14,6 +14,10 @@ #include "mozilla/Assertions.h" // MOZ_ASSERT #include "mozilla/Attributes.h" // MOZ_ALWAYS_INLINE #include "mozilla/Likely.h" // MOZ_LIKELY +#include "mozilla/Maybe.h" +#include "mozilla/Range.h" +#include "mozilla/Span.h" +#include "mozilla/Tuple.h" #include // std::copy_n #include // size_t @@ -27,6 +31,294 @@ class JS_PUBLIC_API JSAtom; class JSLinearString; class JS_PUBLIC_API JSString; +extern JS_PUBLIC_API JSString* JS_GetEmptyString(JSContext* cx); + +// Don't want to export data, so provide accessors for non-inline Values. +extern JS_PUBLIC_API JS::Value JS_GetEmptyStringValue(JSContext* cx); + +/* + * String creation. + * + * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy; + * but on error (signified by null return), it leaves chars owned by the + * caller. So the caller must free bytes in the error case, if it has no use + * for them. In contrast, all the JS_New*StringCopy* functions do not take + * ownership of the character memory passed to them -- they copy it. + */ + +extern JS_PUBLIC_API JSString* JS_NewStringCopyN(JSContext* cx, const char* s, + size_t n); + +extern JS_PUBLIC_API JSString* JS_NewStringCopyZ(JSContext* cx, const char* s); + +extern JS_PUBLIC_API JSString* JS_NewStringCopyUTF8Z( + JSContext* cx, const JS::ConstUTF8CharsZ s); + +extern JS_PUBLIC_API JSString* JS_NewStringCopyUTF8N(JSContext* cx, + const JS::UTF8Chars s); + +extern JS_PUBLIC_API JSString* JS_AtomizeAndPinJSString(JSContext* cx, + JS::HandleString str); + +extern JS_PUBLIC_API JSString* JS_AtomizeStringN(JSContext* cx, const char* s, + size_t length); + +extern JS_PUBLIC_API JSString* JS_AtomizeString(JSContext* cx, const char* s); + +extern JS_PUBLIC_API JSString* JS_AtomizeAndPinStringN(JSContext* cx, + const char* s, + size_t length); + +extern JS_PUBLIC_API JSString* JS_AtomizeAndPinString(JSContext* cx, + const char* s); + +extern JS_PUBLIC_API JSString* JS_NewLatin1String( + JSContext* cx, js::UniquePtr chars, + size_t length); + +extern JS_PUBLIC_API JSString* JS_NewUCString(JSContext* cx, + JS::UniqueTwoByteChars chars, + size_t length); + +extern JS_PUBLIC_API JSString* JS_NewUCStringDontDeflate( + JSContext* cx, JS::UniqueTwoByteChars chars, size_t length); + +extern JS_PUBLIC_API JSString* JS_NewUCStringCopyN(JSContext* cx, + const char16_t* s, size_t n); + +extern JS_PUBLIC_API JSString* JS_NewUCStringCopyZ(JSContext* cx, + const char16_t* s); + +extern JS_PUBLIC_API JSString* JS_AtomizeUCStringN(JSContext* cx, + const char16_t* s, + size_t length); + +extern JS_PUBLIC_API JSString* JS_AtomizeUCString(JSContext* cx, + const char16_t* s); + +extern JS_PUBLIC_API JSString* JS_AtomizeAndPinUCStringN(JSContext* cx, + const char16_t* s, + size_t length); + +extern JS_PUBLIC_API JSString* JS_AtomizeAndPinUCString(JSContext* cx, + const char16_t* s); + +extern JS_PUBLIC_API bool JS_CompareStrings(JSContext* cx, JSString* str1, + JSString* str2, int32_t* result); + +[[nodiscard]] extern JS_PUBLIC_API bool JS_StringEqualsAscii( + JSContext* cx, JSString* str, const char* asciiBytes, bool* match); + +// Same as above, but when the length of asciiBytes (excluding the +// trailing null, if any) is known. +[[nodiscard]] extern JS_PUBLIC_API bool JS_StringEqualsAscii( + JSContext* cx, JSString* str, const char* asciiBytes, size_t length, + bool* match); + +template +[[nodiscard]] bool JS_StringEqualsLiteral(JSContext* cx, JSString* str, + const char (&asciiBytes)[N], + bool* match) { + MOZ_ASSERT(asciiBytes[N - 1] == '\0'); + return JS_StringEqualsAscii(cx, str, asciiBytes, N - 1, match); +} + +extern JS_PUBLIC_API size_t JS_PutEscapedString(JSContext* cx, char* buffer, + size_t size, JSString* str, + char quote); + +/* + * Extracting string characters and length. + * + * While getting the length of a string is infallible, getting the chars can + * fail. As indicated by the lack of a JSContext parameter, there are two + * special cases where getting the chars is infallible: + * + * The first case is for strings that have been atomized, e.g. directly by + * JS_AtomizeAndPinString or implicitly because it is stored in a jsid. + * + * The second case is "linear" strings that have been explicitly prepared in a + * fallible context by JS_EnsureLinearString. To catch errors, a separate opaque + * JSLinearString type is returned by JS_EnsureLinearString and expected by + * JS_Get{Latin1,TwoByte}StringCharsAndLength. Note, though, that this is purely + * a syntactic distinction: the input and output of JS_EnsureLinearString are + * the same actual GC-thing. If a JSString is known to be linear, + * JS_ASSERT_STRING_IS_LINEAR can be used to make a debug-checked cast. Example: + * + * // In a fallible context. + * JSLinearString* lstr = JS_EnsureLinearString(cx, str); + * if (!lstr) { + * return false; + * } + * MOZ_ASSERT(lstr == JS_ASSERT_STRING_IS_LINEAR(str)); + * + * // In an infallible context, for the same 'str'. + * AutoCheckCannotGC nogc; + * const char16_t* chars = JS::GetTwoByteLinearStringChars(nogc, lstr) + * MOZ_ASSERT(chars); + * + * Note: JS strings (including linear strings and atoms) are not + * null-terminated! + * + * Additionally, string characters are stored as either Latin1Char (8-bit) + * or char16_t (16-bit). Clients can use JS::StringHasLatin1Chars and can then + * call either the Latin1* or TwoByte* functions. Some functions like + * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte + * strings. + */ + +extern JS_PUBLIC_API size_t JS_GetStringLength(JSString* str); + +extern JS_PUBLIC_API bool JS_StringIsLinear(JSString* str); + +extern JS_PUBLIC_API const JS::Latin1Char* JS_GetLatin1StringCharsAndLength( + JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str, + size_t* length); + +extern JS_PUBLIC_API const char16_t* JS_GetTwoByteStringCharsAndLength( + JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str, + size_t* length); + +extern JS_PUBLIC_API bool JS_GetStringCharAt(JSContext* cx, JSString* str, + size_t index, char16_t* res); + +extern JS_PUBLIC_API const char16_t* JS_GetTwoByteExternalStringChars( + JSString* str); + +extern JS_PUBLIC_API bool JS_CopyStringChars(JSContext* cx, + mozilla::Range dest, + JSString* str); + +/** + * Copies the string's characters to a null-terminated char16_t buffer. + * + * Returns nullptr on OOM. + */ +extern JS_PUBLIC_API JS::UniqueTwoByteChars JS_CopyStringCharsZ(JSContext* cx, + JSString* str); + +extern JS_PUBLIC_API JSLinearString* JS_EnsureLinearString(JSContext* cx, + JSString* str); + +static MOZ_ALWAYS_INLINE JSLinearString* JSID_TO_LINEAR_STRING(jsid id) { + MOZ_ASSERT(JSID_IS_STRING(id)); + return reinterpret_cast(JSID_TO_STRING(id)); +} + +static MOZ_ALWAYS_INLINE JSLinearString* JS_ASSERT_STRING_IS_LINEAR( + JSString* str) { + MOZ_ASSERT(JS_StringIsLinear(str)); + return reinterpret_cast(str); +} + +static MOZ_ALWAYS_INLINE JSString* JS_FORGET_STRING_LINEARNESS( + JSLinearString* str) { + return reinterpret_cast(str); +} + +/* + * Additional APIs that avoid fallibility when given a linear string. + */ + +extern JS_PUBLIC_API bool JS_LinearStringEqualsAscii(JSLinearString* str, + const char* asciiBytes); +extern JS_PUBLIC_API bool JS_LinearStringEqualsAscii(JSLinearString* str, + const char* asciiBytes, + size_t length); + +template +bool JS_LinearStringEqualsLiteral(JSLinearString* str, + const char (&asciiBytes)[N]) { + MOZ_ASSERT(asciiBytes[N - 1] == '\0'); + return JS_LinearStringEqualsAscii(str, asciiBytes, N - 1); +} + +extern JS_PUBLIC_API size_t JS_PutEscapedLinearString(char* buffer, size_t size, + JSLinearString* str, + char quote); + +/** + * Create a dependent string, i.e., a string that owns no character storage, + * but that refers to a slice of another string's chars. Dependent strings + * are mutable by definition, so the thread safety comments above apply. + */ +extern JS_PUBLIC_API JSString* JS_NewDependentString(JSContext* cx, + JS::HandleString str, + size_t start, + size_t length); + +/** + * Concatenate two strings, possibly resulting in a rope. + * See above for thread safety comments. + */ +extern JS_PUBLIC_API JSString* JS_ConcatStrings(JSContext* cx, + JS::HandleString left, + JS::HandleString right); + +/** + * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before + * the call; on return, *dstlenp contains the number of characters actually + * stored. To determine the necessary destination buffer size, make a sizing + * call that passes nullptr for dst. + * + * On errors, the functions report the error. In that case, *dstlenp contains + * the number of characters or bytes transferred so far. If cx is nullptr, no + * error is reported on failure, and the functions simply return false. + * + * NB: This function does not store an additional zero byte or char16_t after + * the transcoded string. + */ +JS_PUBLIC_API bool JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, + char16_t* dst, size_t* dstlenp); + +/** + * Get number of bytes in the string encoding (without accounting for a + * terminating zero bytes. The function returns (size_t) -1 if the string + * can not be encoded into bytes and reports an error using cx accordingly. + */ +JS_PUBLIC_API size_t JS_GetStringEncodingLength(JSContext* cx, JSString* str); + +/** + * Encode string into a buffer. The function does not stores an additional + * zero byte. The function returns (size_t) -1 if the string can not be + * encoded into bytes with no error reported. Otherwise it returns the number + * of bytes that are necessary to encode the string. If that exceeds the + * length parameter, the string will be cut and only length bytes will be + * written into the buffer. + */ +[[nodiscard]] JS_PUBLIC_API bool JS_EncodeStringToBuffer(JSContext* cx, + JSString* str, + char* buffer, + size_t length); + +/** + * Encode as many scalar values of the string as UTF-8 as can fit + * into the caller-provided buffer replacing unpaired surrogates + * with the REPLACEMENT CHARACTER. + * + * If JS::StringHasLatin1Chars(str) returns true, the function + * is guaranteed to convert the entire string if + * buffer.Length() >= 2 * JS_GetStringLength(str). Otherwise, + * the function is guaranteed to convert the entire string if + * buffer.Length() >= 3 * JS_GetStringLength(str). + * + * This function does not alter the representation of |str| or + * any |JSString*| substring that is a constituent part of it. + * Returns mozilla::Nothing() on OOM, without reporting an error; + * some data may have been written to |buffer| when this happens. + * + * If there's no OOM, returns the number of code units read and + * the number of code units written. + * + * The semantics of this method match the semantics of + * TextEncoder.encodeInto(). + * + * The function does not store an additional zero byte. + */ +JS_PUBLIC_API mozilla::Maybe> +JS_EncodeStringToUTF8BufferPartial(JSContext* cx, JSString* str, + mozilla::Span buffer); + namespace JS { class JS_PUBLIC_API AutoRequireNoGC; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 1d25243f70bb..d9630a0e9ad6 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -13,7 +13,6 @@ #include "mozilla/FloatingPoint.h" #include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/Range.h" #include "mozilla/RangedPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/TimeStamp.h" @@ -46,6 +45,7 @@ #include "js/RealmOptions.h" #include "js/RefCounted.h" #include "js/RootingAPI.h" +#include "js/String.h" #include "js/TracingAPI.h" #include "js/Transcoding.h" #include "js/UniquePtr.h" @@ -168,11 +168,6 @@ JS_PUBLIC_API bool JS_StringHasBeenPinned(JSContext* cx, JSString* str); /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */ extern JS_PUBLIC_API int64_t JS_Now(void); -/** Don't want to export data, so provide accessors for non-inline Values. */ -extern JS_PUBLIC_API JS::Value JS_GetEmptyStringValue(JSContext* cx); - -extern JS_PUBLIC_API JSString* JS_GetEmptyString(JSContext* cx); - extern JS_PUBLIC_API bool JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp); @@ -1918,288 +1913,6 @@ class MOZ_STACK_CLASS JS_PUBLIC_API AutoSetAsyncStackForNewCalls { /************************************************************************/ -/* - * Strings. - * - * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy; - * but on error (signified by null return), it leaves chars owned by the - * caller. So the caller must free bytes in the error case, if it has no use - * for them. In contrast, all the JS_New*StringCopy* functions do not take - * ownership of the character memory passed to them -- they copy it. - */ -extern JS_PUBLIC_API JSString* JS_NewStringCopyN(JSContext* cx, const char* s, - size_t n); - -extern JS_PUBLIC_API JSString* JS_NewStringCopyZ(JSContext* cx, const char* s); - -extern JS_PUBLIC_API JSString* JS_NewStringCopyUTF8Z( - JSContext* cx, const JS::ConstUTF8CharsZ s); - -extern JS_PUBLIC_API JSString* JS_NewStringCopyUTF8N(JSContext* cx, - const JS::UTF8Chars s); - -extern JS_PUBLIC_API JSString* JS_AtomizeAndPinJSString(JSContext* cx, - JS::HandleString str); - -extern JS_PUBLIC_API JSString* JS_AtomizeStringN(JSContext* cx, const char* s, - size_t length); - -extern JS_PUBLIC_API JSString* JS_AtomizeString(JSContext* cx, const char* s); - -extern JS_PUBLIC_API JSString* JS_AtomizeAndPinStringN(JSContext* cx, - const char* s, - size_t length); - -extern JS_PUBLIC_API JSString* JS_AtomizeAndPinString(JSContext* cx, - const char* s); - -extern JS_PUBLIC_API JSString* JS_NewLatin1String( - JSContext* cx, js::UniquePtr chars, - size_t length); - -extern JS_PUBLIC_API JSString* JS_NewUCString(JSContext* cx, - JS::UniqueTwoByteChars chars, - size_t length); - -extern JS_PUBLIC_API JSString* JS_NewUCStringDontDeflate( - JSContext* cx, JS::UniqueTwoByteChars chars, size_t length); - -extern JS_PUBLIC_API JSString* JS_NewUCStringCopyN(JSContext* cx, - const char16_t* s, size_t n); - -extern JS_PUBLIC_API JSString* JS_NewUCStringCopyZ(JSContext* cx, - const char16_t* s); - -extern JS_PUBLIC_API JSString* JS_AtomizeUCStringN(JSContext* cx, - const char16_t* s, - size_t length); - -extern JS_PUBLIC_API JSString* JS_AtomizeUCString(JSContext* cx, - const char16_t* s); - -extern JS_PUBLIC_API JSString* JS_AtomizeAndPinUCStringN(JSContext* cx, - const char16_t* s, - size_t length); - -extern JS_PUBLIC_API JSString* JS_AtomizeAndPinUCString(JSContext* cx, - const char16_t* s); - -extern JS_PUBLIC_API bool JS_CompareStrings(JSContext* cx, JSString* str1, - JSString* str2, int32_t* result); - -[[nodiscard]] extern JS_PUBLIC_API bool JS_StringEqualsAscii( - JSContext* cx, JSString* str, const char* asciiBytes, bool* match); - -// Same as above, but when the length of asciiBytes (excluding the -// trailing null, if any) is known. -[[nodiscard]] extern JS_PUBLIC_API bool JS_StringEqualsAscii( - JSContext* cx, JSString* str, const char* asciiBytes, size_t length, - bool* match); - -template -[[nodiscard]] bool JS_StringEqualsLiteral(JSContext* cx, JSString* str, - const char (&asciiBytes)[N], - bool* match) { - MOZ_ASSERT(asciiBytes[N - 1] == '\0'); - return JS_StringEqualsAscii(cx, str, asciiBytes, N - 1, match); -} - -extern JS_PUBLIC_API size_t JS_PutEscapedString(JSContext* cx, char* buffer, - size_t size, JSString* str, - char quote); - -/* - * Extracting string characters and length. - * - * While getting the length of a string is infallible, getting the chars can - * fail. As indicated by the lack of a JSContext parameter, there are two - * special cases where getting the chars is infallible: - * - * The first case is for strings that have been atomized, e.g. directly by - * JS_AtomizeAndPinString or implicitly because it is stored in a jsid. - * - * The second case is "linear" strings that have been explicitly prepared in a - * fallible context by JS_EnsureLinearString. To catch errors, a separate opaque - * JSLinearString type is returned by JS_EnsureLinearString and expected by - * JS_Get{Latin1,TwoByte}StringCharsAndLength. Note, though, that this is purely - * a syntactic distinction: the input and output of JS_EnsureLinearString are - * the same actual GC-thing. If a JSString is known to be linear, - * JS_ASSERT_STRING_IS_LINEAR can be used to make a debug-checked cast. Example: - * - * // In a fallible context. - * JSLinearString* lstr = JS_EnsureLinearString(cx, str); - * if (!lstr) { - * return false; - * } - * MOZ_ASSERT(lstr == JS_ASSERT_STRING_IS_LINEAR(str)); - * - * // In an infallible context, for the same 'str'. - * AutoCheckCannotGC nogc; - * const char16_t* chars = JS::GetTwoByteLinearStringChars(nogc, lstr) - * MOZ_ASSERT(chars); - * - * Note: JS strings (including linear strings and atoms) are not - * null-terminated! - * - * Additionally, string characters are stored as either Latin1Char (8-bit) - * or char16_t (16-bit). Clients can use JS::StringHasLatin1Chars and can then - * call either the Latin1* or TwoByte* functions. Some functions like - * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte - * strings. - */ - -extern JS_PUBLIC_API size_t JS_GetStringLength(JSString* str); - -extern JS_PUBLIC_API bool JS_StringIsLinear(JSString* str); - -extern JS_PUBLIC_API const JS::Latin1Char* JS_GetLatin1StringCharsAndLength( - JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API const char16_t* JS_GetTwoByteStringCharsAndLength( - JSContext* cx, const JS::AutoRequireNoGC& nogc, JSString* str, - size_t* length); - -extern JS_PUBLIC_API bool JS_GetStringCharAt(JSContext* cx, JSString* str, - size_t index, char16_t* res); - -extern JS_PUBLIC_API const char16_t* JS_GetTwoByteExternalStringChars( - JSString* str); - -extern JS_PUBLIC_API bool JS_CopyStringChars(JSContext* cx, - mozilla::Range dest, - JSString* str); - -/** - * Copies the string's characters to a null-terminated char16_t buffer. - * - * Returns nullptr on OOM. - */ -extern JS_PUBLIC_API JS::UniqueTwoByteChars JS_CopyStringCharsZ(JSContext* cx, - JSString* str); - -extern JS_PUBLIC_API JSLinearString* JS_EnsureLinearString(JSContext* cx, - JSString* str); - -static MOZ_ALWAYS_INLINE JSLinearString* JSID_TO_LINEAR_STRING(jsid id) { - MOZ_ASSERT(JSID_IS_STRING(id)); - return reinterpret_cast(JSID_TO_STRING(id)); -} - -static MOZ_ALWAYS_INLINE JSLinearString* JS_ASSERT_STRING_IS_LINEAR( - JSString* str) { - MOZ_ASSERT(JS_StringIsLinear(str)); - return reinterpret_cast(str); -} - -static MOZ_ALWAYS_INLINE JSString* JS_FORGET_STRING_LINEARNESS( - JSLinearString* str) { - return reinterpret_cast(str); -} - -/* - * Additional APIs that avoid fallibility when given a linear string. - */ - -extern JS_PUBLIC_API bool JS_LinearStringEqualsAscii(JSLinearString* str, - const char* asciiBytes); -extern JS_PUBLIC_API bool JS_LinearStringEqualsAscii(JSLinearString* str, - const char* asciiBytes, - size_t length); - -template -bool JS_LinearStringEqualsLiteral(JSLinearString* str, - const char (&asciiBytes)[N]) { - MOZ_ASSERT(asciiBytes[N - 1] == '\0'); - return JS_LinearStringEqualsAscii(str, asciiBytes, N - 1); -} - -extern JS_PUBLIC_API size_t JS_PutEscapedLinearString(char* buffer, size_t size, - JSLinearString* str, - char quote); - -/** - * Create a dependent string, i.e., a string that owns no character storage, - * but that refers to a slice of another string's chars. Dependent strings - * are mutable by definition, so the thread safety comments above apply. - */ -extern JS_PUBLIC_API JSString* JS_NewDependentString(JSContext* cx, - JS::HandleString str, - size_t start, - size_t length); - -/** - * Concatenate two strings, possibly resulting in a rope. - * See above for thread safety comments. - */ -extern JS_PUBLIC_API JSString* JS_ConcatStrings(JSContext* cx, - JS::HandleString left, - JS::HandleString right); - -/** - * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before - * the call; on return, *dstlenp contains the number of characters actually - * stored. To determine the necessary destination buffer size, make a sizing - * call that passes nullptr for dst. - * - * On errors, the functions report the error. In that case, *dstlenp contains - * the number of characters or bytes transferred so far. If cx is nullptr, no - * error is reported on failure, and the functions simply return false. - * - * NB: This function does not store an additional zero byte or char16_t after - * the transcoded string. - */ -JS_PUBLIC_API bool JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, - char16_t* dst, size_t* dstlenp); - -/** - * Get number of bytes in the string encoding (without accounting for a - * terminating zero bytes. The function returns (size_t) -1 if the string - * can not be encoded into bytes and reports an error using cx accordingly. - */ -JS_PUBLIC_API size_t JS_GetStringEncodingLength(JSContext* cx, JSString* str); - -/** - * Encode string into a buffer. The function does not stores an additional - * zero byte. The function returns (size_t) -1 if the string can not be - * encoded into bytes with no error reported. Otherwise it returns the number - * of bytes that are necessary to encode the string. If that exceeds the - * length parameter, the string will be cut and only length bytes will be - * written into the buffer. - */ -[[nodiscard]] JS_PUBLIC_API bool JS_EncodeStringToBuffer(JSContext* cx, - JSString* str, - char* buffer, - size_t length); - -/** - * Encode as many scalar values of the string as UTF-8 as can fit - * into the caller-provided buffer replacing unpaired surrogates - * with the REPLACEMENT CHARACTER. - * - * If JS::StringHasLatin1Chars(str) returns true, the function - * is guaranteed to convert the entire string if - * buffer.Length() >= 2 * JS_GetStringLength(str). Otherwise, - * the function is guaranteed to convert the entire string if - * buffer.Length() >= 3 * JS_GetStringLength(str). - * - * This function does not alter the representation of |str| or - * any |JSString*| substring that is a constituent part of it. - * Returns mozilla::Nothing() on OOM, without reporting an error; - * some data may have been written to |buffer| when this happens. - * - * If there's no OOM, returns the number of code units read and - * the number of code units written. - * - * The semantics of this method match the semantics of - * TextEncoder.encodeInto(). - * - * The function does not store an additional zero byte. - */ -JS_PUBLIC_API mozilla::Maybe> -JS_EncodeStringToUTF8BufferPartial(JSContext* cx, JSString* str, - mozilla::Span buffer); - namespace JS { JS_PUBLIC_API bool PropertySpecNameEqualsId(JSPropertySpec::Name name,