diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index 9f5de16d92a..ae0b37d0da6 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -516,6 +516,14 @@ XPCConvert::JSData2Native(void* d, HandleValue s, if (!str) { ws->AssignLiteral(MOZ_UTF16("undefined")); + } else if (XPCStringConvert::IsDOMString(str)) { + // The characters represent an existing nsStringBuffer that + // was shared by XPCStringConvert::ReadableToJSVal. + nsStringBuffer::FromData((void *)chars)->ToString(length, *ws); + } else if (XPCStringConvert::IsLiteral(str)) { + // The characters represent a literal char16_t string constant + // compiled into libxul, such as the string "undefined" above. + ws->AssignLiteral(chars, length); } else if (useAllocator && STRING_TO_JSVAL(str) == s) { // The JS string will exist over the function call. // We don't need to copy the characters in this case. diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 9a3165a5145..63ba9cd6de2 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -234,6 +234,18 @@ public: static void FreeZoneCache(JS::Zone *zone); static void ClearZoneCache(JS::Zone *zone); + static MOZ_ALWAYS_INLINE bool IsLiteral(JSString *str) + { + return JS_IsExternalString(str) && + JS_GetExternalStringFinalizer(str) == &sLiteralFinalizer; + } + + static MOZ_ALWAYS_INLINE bool IsDOMString(JSString *str) + { + return JS_IsExternalString(str) && + JS_GetExternalStringFinalizer(str) == &sDOMStringFinalizer; + } + private: static const JSStringFinalizer sLiteralFinalizer, sDOMStringFinalizer; diff --git a/xpcom/string/public/nsTSubstring.h b/xpcom/string/public/nsTSubstring.h index 8eef2c0ddb9..36b609153a6 100644 --- a/xpcom/string/public/nsTSubstring.h +++ b/xpcom/string/public/nsTSubstring.h @@ -834,13 +834,16 @@ class nsTSubstring_CharT mFlags = dataFlags | (mFlags & 0xFFFF0000); } - void NS_FASTCALL AssignLiteral( const char_type* data, size_type length ); void NS_FASTCALL ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length ); static int AppendFunc( void* arg, const char* s, uint32_t len); public: + // NOTE: this method is declared public _only_ for convenience for + // callers who don't have access to the original nsLiteralString_CharT. + void NS_FASTCALL AssignLiteral( const char_type* data, size_type length ); + // mFlags is a bitwise combination of the following flags. the meaning // and interpretation of these flags is an implementation detail. //