#375: M1352323 M1038099

This commit is contained in:
Cameron Kaiser 2019-11-16 20:07:50 -08:00
parent 71e13ff66b
commit eb6f62648e
6 changed files with 58 additions and 6 deletions

View File

@ -1535,6 +1535,15 @@ JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
return s;
}
JS_PUBLIC_API(JSString*)
JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
const JSStringFinalizer* fin, bool* isExternal)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
return NewMaybeExternalString(cx, chars, length, fin, isExternal);
}
extern JS_PUBLIC_API(bool)
JS_IsExternalString(JSString* str)
{

View File

@ -1820,6 +1820,17 @@ extern JS_PUBLIC_API(JSString*)
JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
const JSStringFinalizer* fin);
/**
* Create a new JSString whose chars member may refer to external memory.
* If the returned string refers to the external memory, |*isExternal| is set
* to true. Otherwise the returned string is not an external string and
* |*isExternal| is set to false. If |*isExternal| is false, |fin| won't be
* called.
*/
extern JS_PUBLIC_API(JSString*)
JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
const JSStringFinalizer* fin, bool* isExternal);
/**
* Return whether 'str' was created with JS_NewExternalString or
* JS_NewExternalStringWithClosure.

View File

@ -1213,6 +1213,24 @@ NewStringCopyN<CanGC>(ExclusiveContext* cx, const Latin1Char* s, size_t n);
template JSFlatString*
NewStringCopyN<NoGC>(ExclusiveContext* cx, const Latin1Char* s, size_t n);
JSString*
NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n, const JSStringFinalizer* fin,
bool* isExternal)
{
if (JSString* str = TryEmptyOrStaticString(cx, s, n)) {
*isExternal = false;
return str;
}
if (JSThinInlineString::lengthFits<Latin1Char>(n) && CanStoreCharsAsLatin1(s, n)) {
*isExternal = false;
return NewInlineStringDeflated<AllowGC::CanGC>(cx, mozilla::Range<const char16_t>(s, n));
}
*isExternal = true;
return JSExternalString::new_(cx, s, n, fin);
}
} /* namespace js */
#ifdef DEBUG

View File

@ -1267,6 +1267,10 @@ NewStringCopyZ(js::ExclusiveContext* cx, const char* s)
return NewStringCopyN<allowGC>(cx, s, strlen(s));
}
JSString*
NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n, const JSStringFinalizer* fin,
bool* isExternal);
JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
} /* namespace js */

View File

@ -80,9 +80,10 @@ XPCStringConvert::ReadableToJSVal(JSContext* cx,
uint32_t length = readable.Length();
if (readable.IsLiteral()) {
JSString* str = JS_NewExternalString(cx,
static_cast<const char16_t*>(readable.BeginReading()),
length, &sLiteralFinalizer);
bool ignored;
JSString* str = JS_NewMaybeExternalString(cx,
static_cast<const char16_t*>(readable.BeginReading()),
length, &sLiteralFinalizer, &ignored);
if (!str)
return false;
vp.setString(str);

View File

@ -237,13 +237,22 @@ public:
return true;
}
JSString* str = JS_NewExternalString(cx,
static_cast<char16_t*>(buf->Data()),
length, &sDOMStringFinalizer);
bool isExternal;
JSString* str = JS_NewMaybeExternalString(cx,
static_cast<char16_t*>(buf->Data()),
length, &sDOMStringFinalizer, &isExternal);
if (!str) {
return false;
}
rval.setString(str);
// If JS_NewMaybeExternalString returns non-external string, finalizer
// won't be called. Do not store it to cache.
if (!isExternal) {
*sharedBuffer = false;
return true;
}
if (!cache) {
cache = new ZoneStringCache();
JS_SetZoneUserData(zone, cache);