author | Ted Campbell <tcampbell@mozilla.com> |
Mon, 16 Nov 2020 07:50:13 +0000 | |
changeset 557313 | 7da5f1f192f618be1624e0fa4626433cc083bc0a |
parent 557312 | 722e9e76716baa9b08fb991313c23d32ca43489a |
child 557314 | 17ecebdc6d8b5b4b8fb4e20392f6380928207a14 |
push id | 37957 |
push user | malexandru@mozilla.com |
push date | Tue, 17 Nov 2020 09:44:06 +0000 |
treeherder | mozilla-central@31d67eef91da [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1675670 |
milestone | 84.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -1237,21 +1237,18 @@ static bool FoldAdd(FoldInfo info, Parse next = &(*current)->pn_next; node->unsafeDecrementCount(); } while (*next); // Replace with concatenation if we multiple nodes. if (accum.length() > 1) { // Construct the concatenated atom. - const ParserAtom* combination = - info.parserAtoms - .concatAtoms(info.cx, - mozilla::Range(accum.begin(), accum.length())) - .unwrapOr(nullptr); + const ParserAtom* combination = info.parserAtoms.concatAtoms( + info.cx, mozilla::Range(accum.begin(), accum.length())); if (!combination) { return false; } // Replace |current|'s string with the entire combination. MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr)); (*current)->as<NameNode>().setAtom(combination); }
--- a/js/src/frontend/Frontend2.cpp +++ b/js/src/frontend/Frontend2.cpp @@ -60,17 +60,17 @@ bool ConvertAtoms(JSContext* cx, const S return false; } for (size_t i = 0; i < numAtoms; i++) { auto s = reinterpret_cast<const mozilla::Utf8Unit*>( smoosh_get_atom_at(result, i)); auto len = smoosh_get_atom_len_at(result, i); const ParserAtom* atom = - compilationState.parserAtoms.internUtf8(cx, s, len).unwrapOr(nullptr); + compilationState.parserAtoms.internUtf8(cx, s, len); if (!atom) { return false; } atom->markUsedByStencil(); allAtoms.infallibleAppend(atom); } return true; @@ -305,18 +305,17 @@ bool ConvertRegExpData(JSContext* cx, co LifoAllocScope allocScope(&cx->tempLifoAlloc()); if (!irregexp::CheckPatternSyntax(cx, ts, range, flags)) { return false; } const mozilla::Utf8Unit* sUtf8 = reinterpret_cast<const mozilla::Utf8Unit*>(s); const ParserAtom* atom = - compilationState.parserAtoms.internUtf8(cx, sUtf8, len) - .unwrapOr(nullptr); + compilationState.parserAtoms.internUtf8(cx, sUtf8, len); if (!atom) { return false; } atom->markUsedByStencil(); RegExpIndex index(compilationInfo.stencil.regExpData.length()); if (!compilationInfo.stencil.regExpData.emplaceBack( atom->toIndex(), JS::RegExpFlags(flags))) {
--- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -837,24 +837,24 @@ bool PerHandlerParser<ParseHandler>:: if (handler_.canSkipLazyClosedOverBindings()) { // Scopes are nullptr-delimited in the BaseScript closed over bindings // array. uint32_t slotCount = scope.declaredCount(); while (JSAtom* name = handler_.nextLazyClosedOverBinding()) { // TODO-Stencil // After closed-over-bindings are snapshotted in the handler, // remove this. - auto mbNameId = this->compilationState_.parserAtoms.internJSAtom( - cx_, this->getCompilationInfo(), name); - if (mbNameId.isErr()) { + const ParserAtom* parserAtom = + this->compilationState_.parserAtoms.internJSAtom( + cx_, this->getCompilationInfo(), name); + if (!parserAtom) { return false; } - const ParserName* nameId = mbNameId.unwrap()->asName(); - - scope.lookupDeclaredName(nameId)->value()->setClosedOver(); + + scope.lookupDeclaredName(parserAtom->asName())->value()->setClosedOver(); MOZ_ASSERT(slotCount > 0); slotCount--; } if (pc_->isGeneratorOrAsync()) { scope.setOwnStackSlotCount(slotCount); } return true; @@ -2394,18 +2394,17 @@ const ParserAtom* ParserBase::prefixAcce prefix = cx_->parserNames().setPrefix; } else { MOZ_ASSERT(propType == PropertyType::Getter); prefix = cx_->parserNames().getPrefix; } const ParserAtom* atoms[2] = {prefix, propAtom}; auto atomsRange = mozilla::Range(atoms, 2); - return this->compilationState_.parserAtoms.concatAtoms(cx_, atomsRange) - .unwrapOr(nullptr); + return this->compilationState_.parserAtoms.concatAtoms(cx_, atomsRange); } template <class ParseHandler, typename Unit> void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition( FunctionBox* funbox, TokenPos pos) const { uint32_t startLine, startColumn; tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn); @@ -2739,20 +2738,18 @@ bool Parser<FullParseHandler, Unit>::ski // parse recorded the free variables of nested functions and their extents, // so we can skip over them after accounting for their free variables. RootedFunction fun(cx_, handler_.nextLazyInnerFunction()); // TODO-Stencil: Consider for snapshotting. const ParserAtom* displayAtom = nullptr; if (fun->displayAtom()) { - displayAtom = - this->compilationState_.parserAtoms - .internJSAtom(cx_, this->compilationInfo_, fun->displayAtom()) - .unwrapOr(nullptr); + displayAtom = this->compilationState_.parserAtoms.internJSAtom( + cx_, this->compilationInfo_, fun->displayAtom()); if (!displayAtom) { return false; } } FunctionBox* funbox = newFunctionBox( funNode, displayAtom, fun->flags(), toStringStart, Directives(/* strict = */ false), fun->generatorKind(), fun->asyncKind()); @@ -3231,20 +3228,18 @@ FunctionNode* Parser<FullParseHandler, U FunctionNodeType funNode = handler_.newFunction(syntaxKind, pos()); if (!funNode) { return null(); } // TODO-Stencil: Consider for snapshotting. const ParserAtom* displayAtom = nullptr; if (fun->displayAtom()) { - displayAtom = - this->compilationState_.parserAtoms - .internJSAtom(cx_, this->compilationInfo_, fun->displayAtom()) - .unwrapOr(nullptr); + displayAtom = this->compilationState_.parserAtoms.internJSAtom( + cx_, this->compilationInfo_, fun->displayAtom()); if (!displayAtom) { return null(); } } Directives directives(strict); FunctionBox* funbox = newFunctionBox(funNode, displayAtom, fun->flags(), toStringStart, @@ -10291,19 +10286,18 @@ RegExpLiteral* Parser<FullParseHandler, // skip this. LifoAllocScope allocScope(&cx_->tempLifoAlloc()); if (!irregexp::CheckPatternSyntax(cx_, anyChars, range, flags, Some(line), Some(column))) { return nullptr; } } - const ParserAtom* atom = this->compilationState_.parserAtoms - .internChar16(cx_, chars.begin(), chars.length()) - .unwrapOr(nullptr); + const ParserAtom* atom = this->compilationState_.parserAtoms.internChar16( + cx_, chars.begin(), chars.length()); if (!atom) { return nullptr; } atom->markUsedByStencil(); RegExpIndex index(this->getCompilationInfo().stencil.regExpData.length()); if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) { ReportAllocationOverflow(cx_);
--- a/js/src/frontend/ParserAtom.cpp +++ b/js/src/frontend/ParserAtom.cpp @@ -104,18 +104,16 @@ class InflatedChar16Sequence<LittleEndia } }; } // namespace js namespace js { namespace frontend { -static JS::OOM PARSER_ATOMS_OOM; - JSAtom* GetWellKnownAtom(JSContext* cx, WellKnownAtomId atomId) { #define ASSERT_OFFSET_(idpart, id, text) \ static_assert(offsetof(JSAtomState, id) == \ int32_t(WellKnownAtomId::id) * \ sizeof(js::ImmutablePropertyNamePtr)); FOR_EACH_COMMON_PROPERTYNAME(ASSERT_OFFSET_); #undef ASSERT_OFFSET_ @@ -127,29 +125,25 @@ JSAtom* GetWellKnownAtom(JSContext* cx, #undef ASSERT_OFFSET_ static_assert(int32_t(WellKnownAtomId::abort) == 0, "Unexpected order of WellKnownAtom"); return (&cx->names().abort)[int32_t(atomId)]; } -mozilla::GenericErrorResult<OOM> RaiseParserAtomsOOMError(JSContext* cx) { - js::ReportOutOfMemory(cx); - return mozilla::Err(PARSER_ATOMS_OOM); -} - template <typename CharT, typename SeqCharT> -/* static */ JS::Result<ParserAtomEntry*, OOM> ParserAtomEntry::allocate( +/* static */ ParserAtomEntry* ParserAtomEntry::allocate( JSContext* cx, LifoAlloc& alloc, InflatedChar16Sequence<SeqCharT> seq, uint32_t length, HashNumber hash) { constexpr size_t HeaderSize = sizeof(ParserAtomEntry); void* raw = alloc.alloc(HeaderSize + (sizeof(CharT) * length)); if (!raw) { - return RaiseParserAtomsOOMError(cx); + js::ReportOutOfMemory(cx); + return nullptr; } constexpr bool hasTwoByteChars = (sizeof(CharT) == 2); static_assert(sizeof(CharT) == 1 || sizeof(CharT) == 2, "CharT should be 1 or 2 byte type"); ParserAtomEntry* entry = new (raw) ParserAtomEntry(length, hash, hasTwoByteChars); CharT* entryBuf = entry->chars<CharT>(); @@ -302,57 +296,64 @@ void ParserAtomEntry::dumpCharsNoQuote(j #endif ParserAtomsTable::ParserAtomsTable(JSRuntime* rt, LifoAlloc& alloc, ParserAtomVector& entries) : wellKnownTable_(*rt->commonParserNames), alloc_(alloc), entries_(entries) {} -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::addEntry( - JSContext* cx, EntrySet::AddPtr& addPtr, ParserAtomEntry* entry) { +const ParserAtom* ParserAtomsTable::addEntry(JSContext* cx, + EntrySet::AddPtr& addPtr, + ParserAtomEntry* entry) { MOZ_ASSERT(!addPtr); ParserAtomIndex index = ParserAtomIndex(entries_.length()); if (size_t(index) >= TaggedParserAtomIndex::IndexLimit) { ReportAllocationOverflow(cx); - return mozilla::Err(PARSER_ATOMS_OOM); + return nullptr; } if (!entries_.append(entry)) { - return RaiseParserAtomsOOMError(cx); + js::ReportOutOfMemory(cx); + return nullptr; } entry->setParserAtomIndex(index); if (!entrySet_.add(addPtr, entry)) { - return RaiseParserAtomsOOMError(cx); + js::ReportOutOfMemory(cx); + return nullptr; } return entry->asAtom(); } template <typename AtomCharT, typename SeqCharT> -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internChar16Seq( +const ParserAtom* ParserAtomsTable::internChar16Seq( JSContext* cx, EntrySet::AddPtr& addPtr, HashNumber hash, InflatedChar16Sequence<SeqCharT> seq, uint32_t length) { MOZ_ASSERT(!addPtr); - ParserAtomEntry* entry; - MOZ_TRY_VAR(entry, ParserAtomEntry::allocate<AtomCharT>(cx, alloc_, seq, - length, hash)); + ParserAtomEntry* entry = + ParserAtomEntry::allocate<AtomCharT>(cx, alloc_, seq, length, hash); + if (!entry) { + return nullptr; + } return addEntry(cx, addPtr, entry); } static const uint16_t MAX_LATIN1_CHAR = 0xff; -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internAscii( - JSContext* cx, const char* asciiPtr, uint32_t length) { +const ParserAtom* ParserAtomsTable::internAscii(JSContext* cx, + const char* asciiPtr, + uint32_t length) { // ASCII strings are strict subsets of Latin1 strings. const Latin1Char* latin1Ptr = reinterpret_cast<const Latin1Char*>(asciiPtr); return internLatin1(cx, latin1Ptr, length); } -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internLatin1( - JSContext* cx, const Latin1Char* latin1Ptr, uint32_t length) { +const ParserAtom* ParserAtomsTable::internLatin1(JSContext* cx, + const Latin1Char* latin1Ptr, + uint32_t length) { // Check for tiny strings which are abundant in minified code. if (const ParserAtom* tiny = wellKnownTable_.lookupTiny(latin1Ptr, length)) { return tiny; } // Check for well-known atom. InflatedChar16Sequence<Latin1Char> seq(latin1Ptr, length); SpecificParserAtomLookup<Latin1Char> lookup(seq); @@ -383,23 +384,23 @@ bool ParserAtomVectorBuilder::resize(JSC } if (!entries_.resize(count)) { ReportOutOfMemory(cx); return false; } return true; } -JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internLatin1At( +const ParserAtom* ParserAtomVectorBuilder::internLatin1At( JSContext* cx, const Latin1Char* latin1Ptr, HashNumber hash, uint32_t length, ParserAtomIndex index) { return internAt<Latin1Char, Latin1Char>(cx, latin1Ptr, hash, length, index); } -JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internChar16At( +const ParserAtom* ParserAtomVectorBuilder::internChar16At( JSContext* cx, LittleEndianChars twoByteLE, HashNumber hash, uint32_t length, ParserAtomIndex index) { #ifdef DEBUG InflatedChar16Sequence<LittleEndianChars> seq(twoByteLE, length); bool wide = false; while (seq.hasMore()) { char16_t ch = seq.next(); if (ch > MAX_LATIN1_CHAR) { @@ -410,39 +411,45 @@ JS::Result<const ParserAtom*, OOM> Parse MOZ_ASSERT(wide); #endif return internAt<char16_t, LittleEndianChars>(cx, twoByteLE, hash, length, index); } template <typename CharT, typename SeqCharT, typename InputCharsT> -JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internAt( - JSContext* cx, InputCharsT chars, HashNumber hash, uint32_t length, - ParserAtomIndex index) { +const ParserAtom* ParserAtomVectorBuilder::internAt(JSContext* cx, + InputCharsT chars, + HashNumber hash, + uint32_t length, + ParserAtomIndex index) { InflatedChar16Sequence<SeqCharT> seq(chars, length); #ifdef DEBUG SpecificParserAtomLookup<SeqCharT> lookup(seq); MOZ_ASSERT(wellKnownTable_.lookupTiny(chars, length) == nullptr); MOZ_ASSERT(wellKnownTable_.lookupChar16Seq(lookup) == nullptr); #endif - ParserAtomEntry* entry; - MOZ_TRY_VAR(entry, - ParserAtomEntry::allocate<CharT>(cx, *alloc_, seq, length, hash)); + ParserAtomEntry* entry = + ParserAtomEntry::allocate<CharT>(cx, *alloc_, seq, length, hash); + if (!entry) { + return nullptr; + } + entry->setParserAtomIndex(index); entries_[index] = entry; return entry->asAtom(); } -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internUtf8( - JSContext* cx, const mozilla::Utf8Unit* utf8Ptr, uint32_t nbyte) { +const ParserAtom* ParserAtomsTable::internUtf8(JSContext* cx, + const mozilla::Utf8Unit* utf8Ptr, + uint32_t nbyte) { // Check for tiny strings which are abundant in minified code. // NOTE: The tiny atoms are all ASCII-only so we can directly look at the // UTF-8 data without worrying about surrogates. if (const ParserAtom* tiny = wellKnownTable_.lookupTiny( reinterpret_cast<const Latin1Char*>(utf8Ptr), nbyte)) { return tiny; } @@ -480,18 +487,19 @@ JS::Result<const ParserAtom*, OOM> Parse // Otherwise, add new entry. bool wide = (minEncoding == JS::SmallestEncoding::UTF16); return wide ? internChar16Seq<char16_t>(cx, addPtr, lookup.hash(), seq, length) : internChar16Seq<Latin1Char>(cx, addPtr, lookup.hash(), seq, length); } -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internChar16( - JSContext* cx, const char16_t* char16Ptr, uint32_t length) { +const ParserAtom* ParserAtomsTable::internChar16(JSContext* cx, + const char16_t* char16Ptr, + uint32_t length) { // Check for tiny strings which are abundant in minified code. if (const ParserAtom* tiny = wellKnownTable_.lookupTiny(char16Ptr, length)) { return tiny; } // Check against well-known. InflatedChar16Sequence<char16_t> seq(char16Ptr, length); SpecificParserAtomLookup<char16_t> lookup(seq); @@ -519,64 +527,64 @@ JS::Result<const ParserAtom*, OOM> Parse // Otherwise, add new entry. return wide ? internChar16Seq<char16_t>(cx, addPtr, lookup.hash(), seq, length) : internChar16Seq<Latin1Char>(cx, addPtr, lookup.hash(), seq, length); } -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internJSAtom( +const ParserAtom* ParserAtomsTable::internJSAtom( JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom) { const ParserAtom* parserAtom; { JS::AutoCheckCannotGC nogc; - auto result = + parserAtom = atom->hasLatin1Chars() ? internLatin1(cx, atom->latin1Chars(nogc), atom->length()) : internChar16(cx, atom->twoByteChars(nogc), atom->length()); - if (result.isErr()) { - return result; + if (!parserAtom) { + return nullptr; } - parserAtom = result.unwrap(); } if (parserAtom->isParserAtomIndex()) { ParserAtomIndex index = parserAtom->toParserAtomIndex(); auto& atomCache = compilationInfo.input.atomCache; if (!atomCache.hasAtomAt(index)) { if (!atomCache.setAtomAt(cx, index, atom)) { - return mozilla::Err(PARSER_ATOMS_OOM); + return nullptr; } } } // We should (infallibly) map back to the same JSAtom. MOZ_ASSERT(parserAtom->toJSAtom(cx, compilationInfo.input.atomCache) == atom); return parserAtom; } -JS::Result<const ParserAtom*, OOM> ParserAtomsTable::concatAtoms( +const ParserAtom* ParserAtomsTable::concatAtoms( JSContext* cx, mozilla::Range<const ParserAtom*> atoms) { MOZ_ASSERT(atoms.length() >= 2, "concatAtoms should only be used for multiple inputs"); // Compute final length and encoding. bool catLatin1 = true; uint32_t catLen = 0; for (const ParserAtom* atom : atoms) { if (atom->hasTwoByteChars()) { catLatin1 = false; } // Overflow check here, length if (atom->length() >= (ParserAtomEntry::MAX_LENGTH - catLen)) { - return RaiseParserAtomsOOMError(cx); + js::ReportOutOfMemory(cx); + return nullptr; } catLen += atom->length(); } // Short Latin1 strings must check for both Tiny and WellKnown atoms so simple // concatenate onto stack and use `internLatin1`. if (catLatin1 && (catLen <= WellKnownParserAtoms::MaxWellKnownLength)) { Latin1Char buf[WellKnownParserAtoms::MaxWellKnownLength]; @@ -902,37 +910,34 @@ XDRResult XDRParserAtomDataAt(XDRState<m length) : xdr->codeChars(const_cast<char16_t*>((*atomp)->twoByteChars()), length); } /* Decode the character data. */ MOZ_ASSERT(mode == XDR_DECODE); JSContext* cx = xdr->cx(); - JS::Result<const ParserAtom*, JS::OOM> mbAtom(nullptr); + const ParserAtom* atom = nullptr; if (latin1) { const Latin1Char* chars = nullptr; if (length) { const uint8_t* ptr = nullptr; MOZ_TRY(xdr->peekData(&ptr, length * sizeof(Latin1Char))); chars = reinterpret_cast<const Latin1Char*>(ptr); } - mbAtom = - xdr->frontendAtoms().internLatin1At(cx, chars, hash, length, index); + atom = xdr->frontendAtoms().internLatin1At(cx, chars, hash, length, index); } else { const uint8_t* twoByteCharsLE = nullptr; if (length) { MOZ_TRY(xdr->peekData(&twoByteCharsLE, length * sizeof(char16_t))); } LittleEndianChars leTwoByte(twoByteCharsLE); - mbAtom = + atom = xdr->frontendAtoms().internChar16At(cx, leTwoByte, hash, length, index); } - - const ParserAtom* atom = mbAtom.unwrapOr(nullptr); if (!atom) { return xdr->fail(JS::TranscodeResult_Throw); } // We only transcoded ParserAtoms used for Stencils so on decode, all // ParserAtoms should be marked as in-use by Stencil. atom->markUsedByStencil();
--- a/js/src/frontend/ParserAtom.h +++ b/js/src/frontend/ParserAtom.h @@ -28,18 +28,16 @@ struct CompilationInfo; class ParserAtom; class ParserName; template <typename CharT> class SpecificParserAtomLookup; class ParserAtomsTable; -mozilla::GenericErrorResult<OOM> RaiseParserAtomsOOMError(JSContext* cx); - // An index to map WellKnownParserAtoms to cx->names(). // This is consistent across multiple compilation. // // GetWellKnownAtom in ParserAtom.cpp relies on the fact that // JSAtomState fields and this enum variants use the same order. enum class WellKnownAtomId : uint32_t { #define ENUM_ENTRY_(_, name, _2) name, FOR_EACH_COMMON_PROPERTYNAME(ENUM_ENTRY_) @@ -251,19 +249,19 @@ class alignas(alignof(uint32_t)) ParserA public: // ParserAtomEntries may own their content buffers in variant_, and thus // cannot be copy-constructed - as a new chars would need to be allocated. ParserAtomEntry(const ParserAtomEntry&) = delete; ParserAtomEntry(ParserAtomEntry&& other) = delete; template <typename CharT, typename SeqCharT> - static JS::Result<ParserAtomEntry*, OOM> allocate( - JSContext* cx, LifoAlloc& alloc, InflatedChar16Sequence<SeqCharT> seq, - uint32_t length, HashNumber hash); + static ParserAtomEntry* allocate(JSContext* cx, LifoAlloc& alloc, + InflatedChar16Sequence<SeqCharT> seq, + uint32_t length, HashNumber hash); ParserAtom* asAtom() { return reinterpret_cast<ParserAtom*>(this); } const ParserAtom* asAtom() const { return reinterpret_cast<const ParserAtom*>(this); } inline ParserName* asName(); inline const ParserName* asName() const; @@ -669,44 +667,43 @@ class ParserAtomsTable { public: ParserAtomsTable(JSRuntime* rt, LifoAlloc& alloc, ParserAtomVector& entries); ParserAtomsTable(ParserAtomsTable&&) = default; private: // Internal APIs for interning to the table after well-known atoms cases have // been tested. - JS::Result<const ParserAtom*, OOM> addEntry(JSContext* cx, - EntrySet::AddPtr& addPtr, - ParserAtomEntry* entry); + const ParserAtom* addEntry(JSContext* cx, EntrySet::AddPtr& addPtr, + ParserAtomEntry* entry); template <typename AtomCharT, typename SeqCharT> - JS::Result<const ParserAtom*, OOM> internChar16Seq( - JSContext* cx, EntrySet::AddPtr& addPtr, HashNumber hash, - InflatedChar16Sequence<SeqCharT> seq, uint32_t length); + const ParserAtom* internChar16Seq(JSContext* cx, EntrySet::AddPtr& addPtr, + HashNumber hash, + InflatedChar16Sequence<SeqCharT> seq, + uint32_t length); public: - JS::Result<const ParserAtom*, OOM> internAscii(JSContext* cx, - const char* asciiPtr, - uint32_t length); + const ParserAtom* internAscii(JSContext* cx, const char* asciiPtr, + uint32_t length); - JS::Result<const ParserAtom*, OOM> internLatin1( - JSContext* cx, const JS::Latin1Char* latin1Ptr, uint32_t length); + const ParserAtom* internLatin1(JSContext* cx, const JS::Latin1Char* latin1Ptr, + uint32_t length); - JS::Result<const ParserAtom*, OOM> internUtf8( - JSContext* cx, const mozilla::Utf8Unit* utf8Ptr, uint32_t nbyte); + const ParserAtom* internUtf8(JSContext* cx, const mozilla::Utf8Unit* utf8Ptr, + uint32_t nbyte); - JS::Result<const ParserAtom*, OOM> internChar16(JSContext* cx, - const char16_t* char16Ptr, - uint32_t length); + const ParserAtom* internChar16(JSContext* cx, const char16_t* char16Ptr, + uint32_t length); - JS::Result<const ParserAtom*, OOM> internJSAtom( - JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom); + const ParserAtom* internJSAtom(JSContext* cx, + CompilationInfo& compilationInfo, + JSAtom* atom); - JS::Result<const ParserAtom*, OOM> concatAtoms( - JSContext* cx, mozilla::Range<const ParserAtom*> atoms); + const ParserAtom* concatAtoms(JSContext* cx, + mozilla::Range<const ParserAtom*> atoms); const ParserAtom* getWellKnown(WellKnownAtomId atomId) const; const ParserAtom* getStatic1(StaticParserString1 s) const; const ParserAtom* getStatic2(StaticParserString2 s) const; const ParserAtom* getParserAtom(ParserAtomIndex index) const; const ParserAtom* getParserAtom(TaggedParserAtomIndex index) const; }; @@ -721,29 +718,30 @@ class ParserAtomVectorBuilder { public: ParserAtomVectorBuilder(JSRuntime* rt, LifoAlloc& alloc, ParserAtomVector& entries); bool resize(JSContext* cx, size_t count); size_t length() const { return entries_.length(); } - JS::Result<const ParserAtom*, OOM> internLatin1At( - JSContext* cx, const JS::Latin1Char* latin1Ptr, HashNumber hash, - uint32_t length, ParserAtomIndex index); + const ParserAtom* internLatin1At(JSContext* cx, + const JS::Latin1Char* latin1Ptr, + HashNumber hash, uint32_t length, + ParserAtomIndex index); - JS::Result<const ParserAtom*, OOM> internChar16At( - JSContext* cx, const LittleEndianChars twoByteLE, HashNumber hash, - uint32_t length, ParserAtomIndex index); + const ParserAtom* internChar16At(JSContext* cx, + const LittleEndianChars twoByteLE, + HashNumber hash, uint32_t length, + ParserAtomIndex index); private: template <typename CharT, typename SeqCharT, typename InputCharsT> - JS::Result<const ParserAtom*, OOM> internAt(JSContext* cx, InputCharsT chars, - HashNumber hash, uint32_t length, - ParserAtomIndex index); + const ParserAtom* internAt(JSContext* cx, InputCharsT chars, HashNumber hash, + uint32_t length, ParserAtomIndex index); public: const ParserAtom* getWellKnown(WellKnownAtomId atomId) const; const ParserAtom* getStatic1(StaticParserString1 s) const; const ParserAtom* getStatic2(StaticParserString2 s) const; const ParserAtom* getParserAtom(ParserAtomIndex index) const; const ParserAtom* getParserAtom(TaggedParserAtomIndex index) const; };
--- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -1537,24 +1537,24 @@ class TokenStreamCharsShared { */ static constexpr MOZ_ALWAYS_INLINE MOZ_MUST_USE bool isAsciiCodePoint( int32_t unit) { return mozilla::IsAscii(static_cast<char32_t>(unit)); } const ParserAtom* drainCharBufferIntoAtom() { // Add to parser atoms table. - auto maybeId = this->parserAtoms->internChar16(cx, charBuffer.begin(), - charBuffer.length()); - if (maybeId.isErr()) { + const ParserAtom* atom = this->parserAtoms->internChar16( + cx, charBuffer.begin(), charBuffer.length()); + if (!atom) { return nullptr; } charBuffer.clear(); - return maybeId.unwrap(); + return atom; } protected: void adoptState(TokenStreamCharsShared& other) { // The other stream's buffer may contain information for a // gotten-then-ungotten token, that we must transfer into this stream so // that token's final get behaves as desired. charBuffer = std::move(other.charBuffer); @@ -1695,26 +1695,24 @@ template <typename Unit> inline void TokenStreamCharsBase<Unit>::consumeKnownCodeUnit(int32_t unit) { sourceUnits.consumeKnownCodeUnit(toUnit(unit)); } template <> MOZ_ALWAYS_INLINE const ParserAtom* TokenStreamCharsBase<char16_t>::atomizeSourceChars( mozilla::Span<const char16_t> units) { - return this->parserAtoms->internChar16(cx, units.data(), units.size()) - .unwrapOr(nullptr); + return this->parserAtoms->internChar16(cx, units.data(), units.size()); } template <> /* static */ MOZ_ALWAYS_INLINE const ParserAtom* TokenStreamCharsBase<mozilla::Utf8Unit>::atomizeSourceChars( mozilla::Span<const mozilla::Utf8Unit> units) { - return this->parserAtoms->internUtf8(cx, units.data(), units.size()) - .unwrapOr(nullptr); + return this->parserAtoms->internUtf8(cx, units.data(), units.size()); } template <typename Unit> class SpecializedTokenStreamCharsBase; template <> class SpecializedTokenStreamCharsBase<char16_t> : public TokenStreamCharsBase<char16_t> {
--- a/js/src/jsapi-tests/testParserAtom.cpp +++ b/js/src/jsapi-tests/testParserAtom.cpp @@ -29,28 +29,28 @@ BEGIN_TEST(testParserAtom_empty) { const char16_t char16[] = {}; const uint8_t bytes[] = {}; const js::LittleEndianChars leTwoByte(bytes); // Check that the well-known empty atom matches for different entry points. const ParserAtom* ref = cx->parserNames().empty; CHECK(ref); - CHECK(atomTable.internAscii(cx, ascii, 0).unwrap() == ref); - CHECK(atomTable.internLatin1(cx, latin1, 0).unwrap() == ref); - CHECK(atomTable.internUtf8(cx, utf8, 0).unwrap() == ref); - CHECK(atomTable.internChar16(cx, char16, 0).unwrap() == ref); + CHECK(atomTable.internAscii(cx, ascii, 0) == ref); + CHECK(atomTable.internLatin1(cx, latin1, 0) == ref); + CHECK(atomTable.internUtf8(cx, utf8, 0) == ref); + CHECK(atomTable.internChar16(cx, char16, 0) == ref); // Check concatenation works on empty atoms. const ParserAtom* concat[] = { cx->parserNames().empty, cx->parserNames().empty, }; mozilla::Range<const ParserAtom*> concatRange(concat, 2); - CHECK(atomTable.concatAtoms(cx, concatRange).unwrap() == ref); + CHECK(atomTable.concatAtoms(cx, concatRange) == ref); return true; } END_TEST(testParserAtom_empty) // Test length-1 fast-path is consistent across entry points. BEGIN_TEST(testParserAtom_tiny1) { using js::frontend::ParserAtom; @@ -67,27 +67,27 @@ BEGIN_TEST(testParserAtom_tiny1) { const mozilla::Utf8Unit utf8[] = {mozilla::Utf8Unit('a')}; char16_t char16[] = {'a'}; const uint8_t bytes[] = {'a', 0}; const js::LittleEndianChars leTwoByte(bytes); const ParserAtom* ref = cx->parserNames().lookupTiny(&a, 1); CHECK(ref); - CHECK(atomTable.internAscii(cx, ascii, 1).unwrap() == ref); - CHECK(atomTable.internLatin1(cx, latin1, 1).unwrap() == ref); - CHECK(atomTable.internUtf8(cx, utf8, 1).unwrap() == ref); - CHECK(atomTable.internChar16(cx, char16, 1).unwrap() == ref); + CHECK(atomTable.internAscii(cx, ascii, 1) == ref); + CHECK(atomTable.internLatin1(cx, latin1, 1) == ref); + CHECK(atomTable.internUtf8(cx, utf8, 1) == ref); + CHECK(atomTable.internChar16(cx, char16, 1) == ref); const ParserAtom* concat[] = { ref, cx->parserNames().empty, }; mozilla::Range<const ParserAtom*> concatRange(concat, 2); - CHECK(atomTable.concatAtoms(cx, concatRange).unwrap() == ref); + CHECK(atomTable.concatAtoms(cx, concatRange) == ref); // Note: If Latin1-Extended characters become supported, then UTF-8 behaviour // should be tested. char16_t ae = 0x00E6; CHECK(cx->parserNames().lookupTiny(&ae, 1) == nullptr); return true; } @@ -109,27 +109,27 @@ BEGIN_TEST(testParserAtom_tiny2) { mozilla::Utf8Unit('0')}; char16_t char16[] = {'a', '0'}; const uint8_t bytes[] = {'a', 0, '0', 0}; const js::LittleEndianChars leTwoByte(bytes); const ParserAtom* ref = cx->parserNames().lookupTiny(ascii, 2); CHECK(ref); - CHECK(atomTable.internAscii(cx, ascii, 2).unwrap() == ref); - CHECK(atomTable.internLatin1(cx, latin1, 2).unwrap() == ref); - CHECK(atomTable.internUtf8(cx, utf8, 2).unwrap() == ref); - CHECK(atomTable.internChar16(cx, char16, 2).unwrap() == ref); + CHECK(atomTable.internAscii(cx, ascii, 2) == ref); + CHECK(atomTable.internLatin1(cx, latin1, 2) == ref); + CHECK(atomTable.internUtf8(cx, utf8, 2) == ref); + CHECK(atomTable.internChar16(cx, char16, 2) == ref); const ParserAtom* concat[] = { cx->parserNames().lookupTiny(ascii + 0, 1), cx->parserNames().lookupTiny(ascii + 1, 1), }; mozilla::Range<const ParserAtom*> concatRange(concat, 2); - CHECK(atomTable.concatAtoms(cx, concatRange).unwrap() == ref); + CHECK(atomTable.concatAtoms(cx, concatRange) == ref); // Note: If Latin1-Extended characters become supported, then UTF-8 behaviour // should be tested. char16_t ae0[] = {0x00E6, '0'}; CHECK(cx->parserNames().lookupTiny(ae0, 2) == nullptr); return true; } @@ -145,29 +145,29 @@ BEGIN_TEST(testParserAtom_concat) { ParserAtomsTable atomTable(cx->runtime(), alloc, atoms); auto CheckConcat = [&](const char16_t* exp, std::initializer_list<const char16_t*> args) -> bool { // Intern each argument literal std::vector<const ParserAtom*> inputs; for (const char16_t* arg : args) { size_t len = std::char_traits<char16_t>::length(arg); - const ParserAtom* atom = atomTable.internChar16(cx, arg, len).unwrap(); + const ParserAtom* atom = atomTable.internChar16(cx, arg, len); inputs.push_back(atom); } // Concatenate twice to test new vs existing pathways. mozilla::Range<const ParserAtom*> range(inputs.data(), inputs.size()); - const ParserAtom* once = atomTable.concatAtoms(cx, range).unwrap(); - const ParserAtom* twice = atomTable.concatAtoms(cx, range).unwrap(); + const ParserAtom* once = atomTable.concatAtoms(cx, range); + const ParserAtom* twice = atomTable.concatAtoms(cx, range); // Intern expected value literal _after_ the concat code to allow // allocation pathways a chance to be tested. size_t exp_len = std::char_traits<char16_t>::length(exp); - const ParserAtom* ref = atomTable.internChar16(cx, exp, exp_len).unwrap(); + const ParserAtom* ref = atomTable.internChar16(cx, exp, exp_len); return (once == ref) && (twice == ref); }; // Checks empty strings CHECK(CheckConcat(u"", {u"", u""})); CHECK(CheckConcat(u"", {u"", u"", u"", u""})); CHECK(CheckConcat(u"A", {u"", u"", u"A", u""}));
--- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -869,17 +869,17 @@ const frontend::ParserAtom* js::Int32ToP char* start = BackfillInt32InBuffer( si, buffer, JSFatInlineString::MAX_LENGTH_TWO_BYTE + 1, &length); Maybe<uint32_t> indexValue; if (si >= 0) { indexValue.emplace(si); } - return parserAtoms.internAscii(cx, start, length).unwrapOr(nullptr); + return parserAtoms.internAscii(cx, start, length); } /* Returns a non-nullptr pointer to inside cbuf. */ static char* Int32ToCString(ToCStringBuf* cbuf, int32_t i, size_t* len, int base = 10) { uint32_t u = Abs(i); RangedPtr<char> cp(cbuf->sbuf + ToCStringBuf::sbufSize - 1, cbuf->sbuf, @@ -1675,17 +1675,17 @@ const frontend::ParserAtom* js::NumberTo if (!numStr) { ReportOutOfMemory(cx); return nullptr; } MOZ_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize); size_t length = strlen(numStr); - return parserAtoms.internAscii(cx, numStr, length).unwrapOr(nullptr); + return parserAtoms.internAscii(cx, numStr, length); } JSLinearString* js::IndexToString(JSContext* cx, uint32_t index) { if (StaticStrings::hasUint(index)) { return cx->staticStrings().getUint(index); } Realm* realm = cx->realm();
--- a/js/src/util/StringBuffer.cpp +++ b/js/src/util/StringBuffer.cpp @@ -157,30 +157,32 @@ JSAtom* StringBuffer::finishAtom() { const frontend::ParserAtom* StringBuffer::finishParserAtom( frontend::ParserAtomsTable& parserAtoms) { size_t len = length(); if (len == 0) { return cx_->parserNames().empty; } if (isLatin1()) { - auto result = parserAtoms.internLatin1(cx_, latin1Chars().begin(), len); - if (result.isErr()) { + const frontend::ParserAtom* result = + parserAtoms.internLatin1(cx_, latin1Chars().begin(), len); + if (!result) { return nullptr; } latin1Chars().clear(); - return result.unwrap(); + return result; } - auto result = parserAtoms.internChar16(cx_, twoByteChars().begin(), len); - if (result.isErr()) { + const frontend::ParserAtom* result = + parserAtoms.internChar16(cx_, twoByteChars().begin(), len); + if (!result) { return nullptr; } twoByteChars().clear(); - return result.unwrap(); + return result; } bool js::ValueToStringBufferSlow(JSContext* cx, const Value& arg, StringBuffer& sb) { RootedValue v(cx, arg); if (!ToPrimitive(cx, JSTYPE_STRING, &v)) { return false; }
--- a/js/src/vm/Instrumentation.cpp +++ b/js/src/vm/Instrumentation.cpp @@ -94,20 +94,18 @@ static bool StringToInstrumentationKind( } /* static */ const frontend::ParserAtom* RealmInstrumentation::getInstrumentationKindName( JSContext* cx, frontend::ParserAtomsTable& parserAtoms, InstrumentationKind kind) { for (size_t i = 0; i < mozilla::ArrayLength(instrumentationNames); i++) { if (kind == (InstrumentationKind)(1 << i)) { - return parserAtoms - .internAscii(cx, instrumentationNames[i], - strlen(instrumentationNames[i])) - .unwrapOr(nullptr); + return parserAtoms.internAscii(cx, instrumentationNames[i], + strlen(instrumentationNames[i])); } } MOZ_CRASH("Unexpected instrumentation kind"); } /* static */ bool RealmInstrumentation::install(JSContext* cx, Handle<GlobalObject*> global, HandleObject callbackArg,
--- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -1381,23 +1381,23 @@ class MOZ_STACK_CLASS ModuleValidatorSha {"abs", AsmJSMathBuiltin_abs}, {"atan2", AsmJSMathBuiltin_atan2}, {"imul", AsmJSMathBuiltin_imul}, {"clz32", AsmJSMathBuiltin_clz32}, {"fround", AsmJSMathBuiltin_fround}, {"min", AsmJSMathBuiltin_min}, {"max", AsmJSMathBuiltin_max}, }; auto AddMathFunction = [this](const char* name, AsmJSMathBuiltinFunction func) { - auto mbAtom = parserAtoms_.internAscii(cx_, name, strlen(name)); - if (mbAtom.isErr()) { + const ParserAtom* atom = + parserAtoms_.internAscii(cx_, name, strlen(name)); + if (!atom) { return false; } MathBuiltin builtin(func); - return this->standardLibraryMathNames_.putNew(mbAtom.unwrap()->asName(), - builtin); + return this->standardLibraryMathNames_.putNew(atom->asName(), builtin); }; for (const auto& info : functions) { if (!AddMathFunction(info.name, info.func)) { return false; } } @@ -1411,23 +1411,23 @@ class MOZ_STACK_CLASS ModuleValidatorSha {"LOG2E", M_LOG2E}, {"LOG10E", M_LOG10E}, {"PI", M_PI}, {"SQRT1_2", M_SQRT1_2}, {"SQRT2", M_SQRT2}, }; auto AddMathConstant = [this](const char* name, double cst) { - auto mbAtom = parserAtoms_.internAscii(cx_, name, strlen(name)); - if (mbAtom.isErr()) { + const ParserAtom* atom = + parserAtoms_.internAscii(cx_, name, strlen(name)); + if (!atom) { return false; } MathBuiltin builtin(cst); - return this->standardLibraryMathNames_.putNew(mbAtom.unwrap()->asName(), - builtin); + return this->standardLibraryMathNames_.putNew(atom->asName(), builtin); }; for (const auto& info : constants) { if (!AddMathConstant(info.name, info.value)) { return false; } }