Bug 1839396 part 9 - Add Sprinter::releaseJS. r=mgaudet

Sprinter::releaseJS centralize a mechanism which used in many places across the
JS engine, and replaces it with a single function call as well as democratising
the proper handling of UTF8 which might be added to Sprinter allocated strings.

Differential Revision: https://phabricator.services.mozilla.com/D181494
This commit is contained in:
Nicolas B. Pierron 2023-10-04 15:18:15 +00:00
Родитель 0db6013480
Коммит 2bb0a61131
5 изменённых файлов: 63 добавлений и 28 удалений

Просмотреть файл

@ -117,6 +117,7 @@ class JS_PUBLIC_API Sprinter final : public GenericPrinter {
return base;
}
JS::UniqueChars release();
JSString* releaseJS(JSContext* cx);
// Attempt to reserve len + 1 space (for a trailing nullptr byte). If the
// attempt succeeds, return a pointer to the start of that space and adjust

Просмотреть файл

@ -1807,7 +1807,7 @@ static bool DisassembleNative(JSContext* cx, unsigned argc, Value* vp) {
fclose(f);
}
JSString* str = JS_NewStringCopyZ(cx, sprinter.string());
JSString* str = sprinter.releaseJS(cx);
if (!str) {
return false;
}
@ -6971,11 +6971,7 @@ static bool GetStringRepresentation(JSContext* cx, unsigned argc, Value* vp) {
}
str->dumpRepresentation(out, 0);
if (out.hadOutOfMemory()) {
return false;
}
JSString* rep = JS_NewStringCopyN(cx, out.string(), out.getOffset());
JSString* rep = out.releaseJS(cx);
if (!rep) {
return false;
}

Просмотреть файл

@ -3407,7 +3407,7 @@ static bool Notes(JSContext* cx, unsigned argc, Value* vp) {
}
}
JSString* str = JS_NewStringCopyZ(cx, sprinter.string());
JSString* str = sprinter.releaseJS(cx);
if (!str) {
return false;
}
@ -3502,16 +3502,7 @@ static bool DisassembleToString(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
const char* chars = sprinter.string();
size_t len;
JS::UniqueTwoByteChars buf(
JS::LossyUTF8CharsToNewTwoByteCharsZ(
cx, JS::UTF8Chars(chars, strlen(chars)), &len, js::MallocArena)
.get());
if (!buf) {
return false;
}
JSString* str = JS_NewUCStringCopyN(cx, buf.get(), len);
JSString* str = sprinter.releaseJS(cx);
if (!str) {
return false;
}

Просмотреть файл

@ -2798,11 +2798,7 @@ JSString* JS::GetPCCountScriptSummary(JSContext* cx, size_t index) {
json.endObject();
if (sp.hadOutOfMemory()) {
return nullptr;
}
return NewStringCopyZ<CanGC>(cx, sp.string());
return sp.releaseJS(cx);
}
static bool GetPCCountJSON(JSContext* cx, const ScriptAndCounts& sac,
@ -2962,11 +2958,7 @@ JSString* JS::GetPCCountScriptContents(JSContext* cx, size_t index) {
}
}
if (sp.hadOutOfMemory()) {
return nullptr;
}
return NewStringCopyZ<CanGC>(cx, sp.string());
return sp.releaseJS(cx);
}
struct CollectedScripts {

Просмотреть файл

@ -141,11 +141,12 @@ void Sprinter::checkInvariants() const {
}
UniqueChars Sprinter::release() {
checkInvariants();
if (hadOOM_) {
forwardOutOfMemory();
return nullptr;
}
checkInvariants();
char* str = base;
base = nullptr;
offset = size = 0;
@ -155,6 +156,60 @@ UniqueChars Sprinter::release() {
return UniqueChars(str);
}
JSString* Sprinter::releaseJS(JSContext* cx) {
if (hadOOM_) {
MOZ_ASSERT_IF(maybeCx, maybeCx == cx);
forwardOutOfMemory();
return nullptr;
}
checkInvariants();
// Extract Sprinter data.
size_t len = length();
UniqueChars str(base);
// Reset Sprinter.
base = nullptr;
offset = 0;
size = 0;
#ifdef DEBUG
initialized = false;
#endif
// Convert extracted data to a JSString, reusing the current buffer whenever
// possible.
JS::UTF8Chars utf8(str.get(), len);
JS::SmallestEncoding encoding = JS::FindSmallestEncoding(utf8);
if (encoding == JS::SmallestEncoding::ASCII) {
UniqueLatin1Chars latin1(reinterpret_cast<JS::Latin1Char*>(str.release()));
return js::NewString<js::CanGC>(cx, std::move(latin1), len);
}
size_t length;
if (encoding == JS::SmallestEncoding::Latin1) {
UniqueLatin1Chars latin1(
UTF8CharsToNewLatin1CharsZ(cx, utf8, &length, js::StringBufferArena)
.get());
if (!latin1) {
return nullptr;
}
return js::NewString<js::CanGC>(cx, std::move(latin1), length);
}
MOZ_ASSERT(encoding == JS::SmallestEncoding::UTF16);
UniqueTwoByteChars utf16(
UTF8CharsToNewTwoByteCharsZ(cx, utf8, &length, js::StringBufferArena)
.get());
if (!utf16) {
return nullptr;
}
return js::NewString<js::CanGC>(cx, std::move(utf16), length);
}
char* Sprinter::reserve(size_t len) {
InvariantChecker ic(this);