Skip to content

Commit 68f262e

Browse files
committed
Bug 1658593 - Bugfixes in ParserAtoms implementation. r=tcampbell
Differential Revision: https://phabricator.services.mozilla.com/D86734 UltraBlame original commit: 8eb8e0e50e9358a9efb4f47f90769a5d95a81f2e
1 parent 254d0f2 commit 68f262e

File tree

2 files changed

+58
-32
lines changed

2 files changed

+58
-32
lines changed

js/src/frontend/ParserAtom.cpp

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,26 +101,28 @@ bool ParserAtomEntry::equalsJSAtom(JSAtom* other) const {
101101
: EqualChars(latin1Chars(), other->twoByteChars(nogc), length_);
102102
}
103103

104-
UniqueChars ParserAtomToPrintableString(JSContext* cx, const ParserAtom* atom) {
104+
template <typename CharT>
105+
UniqueChars ToPrintableStringImpl(JSContext* cx, mozilla::Range<CharT> str) {
105106
Sprinter sprinter(cx);
106107
if (!sprinter.init()) {
107108
return nullptr;
108109
}
109-
size_t length = atom->length();
110-
if (atom->hasLatin1Chars()) {
111-
if (!QuoteString<QuoteTarget::String>(
112-
&sprinter, mozilla::Range(atom->latin1Chars(), length))) {
113-
return nullptr;
114-
}
115-
} else {
116-
if (!QuoteString<QuoteTarget::String>(
117-
&sprinter, mozilla::Range(atom->twoByteChars(), length))) {
118-
return nullptr;
119-
}
110+
if (!QuoteString<QuoteTarget::String>(&sprinter, str)) {
111+
return nullptr;
120112
}
121113
return sprinter.release();
122114
}
123115

116+
UniqueChars ParserAtomToPrintableString(JSContext* cx, const ParserAtom* atom) {
117+
size_t length = atom->length();
118+
119+
return atom->hasLatin1Chars()
120+
? ToPrintableStringImpl(
121+
cx, mozilla::Range(atom->latin1Chars(), length))
122+
: ToPrintableStringImpl(
123+
cx, mozilla::Range(atom->twoByteChars(), length));
124+
}
125+
124126
bool ParserAtomEntry::isIndex(uint32_t* indexp) const {
125127
size_t len = length();
126128
if (len == 0 || len > UINT32_CHAR_BUFFER_LENGTH) {
@@ -155,6 +157,16 @@ bool ParserAtomEntry::toNumber(JSContext* cx, double* result) const {
155157
: CharsToNumber(cx, twoByteChars(), length(), result);
156158
}
157159

160+
#if defined(DEBUG) || defined(JS_JITSPEW)
161+
void ParserAtomEntry::dumpCharsNoQuote(js::GenericPrinter& out) const {
162+
if (hasLatin1Chars()) {
163+
JSString::dumpCharsNoQuote<Latin1Char>(latin1Chars(), length(), out);
164+
} else {
165+
JSString::dumpCharsNoQuote<char16_t>(twoByteChars(), length(), out);
166+
}
167+
}
168+
#endif
169+
158170
ParserAtomsTable::ParserAtomsTable(JSContext* cx)
159171
: entrySet_(cx), wellKnownTable_(*cx->runtime()->commonParserNames) {}
160172

@@ -425,21 +437,37 @@ bool WellKnownParserAtoms::initSingle(JSContext* cx, const ParserName** name,
425437
MOZ_ASSERT(FindSmallestEncoding(UTF8Chars(str, len)) ==
426438
JS::SmallestEncoding::ASCII);
427439

428-
UniqueLatin1Chars copy(cx->pod_malloc<Latin1Char>(len));
429-
if (!copy) {
430-
return false;
431-
}
432-
mozilla::PodCopy(copy.get(), reinterpret_cast<const Latin1Char*>(str), len);
433-
434-
InflatedChar16Sequence<Latin1Char> seq(copy.get(), len);
440+
InflatedChar16Sequence<Latin1Char> seq(
441+
reinterpret_cast<const Latin1Char*>(str), len);
435442
SpecificParserAtomLookup<Latin1Char> lookup(seq);
443+
HashNumber hash = lookup.hash();
436444

437-
auto maybeEntry =
438-
ParserAtomEntry::allocate(cx, std::move(copy), len, lookup.hash());
439-
if (maybeEntry.isErr()) {
440-
return false;
445+
UniquePtr<ParserAtomEntry> entry = nullptr;
446+
447+
448+
if (len <= ParserAtomEntry::MaxInline<Latin1Char>()) {
449+
auto maybeEntry =
450+
ParserAtomEntry::allocateInline<Latin1Char>(cx, seq, len, hash);
451+
if (maybeEntry.isErr()) {
452+
return false;
453+
}
454+
entry = maybeEntry.unwrap();
455+
456+
457+
} else {
458+
UniqueLatin1Chars copy(cx->pod_malloc<Latin1Char>(len));
459+
if (!copy) {
460+
return false;
461+
}
462+
mozilla::PodCopy(copy.get(), reinterpret_cast<const Latin1Char*>(str), len);
463+
auto maybeEntry = ParserAtomEntry::allocate(cx, std::move(copy), len, hash);
464+
if (maybeEntry.isErr()) {
465+
return false;
466+
}
467+
entry = maybeEntry.unwrap();
441468
}
442-
UniquePtr<ParserAtomEntry> entry = maybeEntry.unwrap();
469+
470+
443471
const ParserName* nm = entry.get()->asName();
444472
if (!entrySet_.putNew(lookup, std::move(entry))) {
445473
return false;

js/src/frontend/ParserAtom.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ mozilla::GenericErrorResult<OOM&> RaiseParserAtomsOOMError(JSContext* cx);
4343

4444
class alignas(alignof(void*)) ParserAtomEntry {
4545
friend class ParserAtomsTable;
46+
friend class WellKnownParserAtoms;
4647

4748
template <typename CharT>
4849
static constexpr uint32_t MaxInline() {
@@ -279,6 +280,10 @@ class alignas(alignof(void*)) ParserAtomEntry {
279280

280281

281282
bool toNumber(JSContext* cx, double* result) const;
283+
284+
#if defined(DEBUG) || defined(JS_JITSPEW)
285+
void dumpCharsNoQuote(js::GenericPrinter& out) const;
286+
#endif
282287
};
283288

284289
class ParserAtom : public ParserAtomEntry {
@@ -483,22 +488,15 @@ inline bool ParserAtomEntry::equalsSeq(
483488
return false;
484489
}
485490
}
486-
if (seq.hasMore()) {
487-
return false;
488-
}
489-
490491
} else {
491492
const Latin1Char* chars = latin1Chars();
492493
for (uint32_t i = 0; i < length_; i++) {
493494
if (!seq.hasMore() || char16_t(chars[i]) != seq.next()) {
494495
return false;
495496
}
496497
}
497-
if (seq.hasMore()) {
498-
return false;
499-
}
500498
}
501-
return true;
499+
return !seq.hasMore();
502500
}
503501

504502
}

0 commit comments

Comments
 (0)