зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1676688 - Part 3: Merge AtomIndex and ParserAtomIndex. r=tcampbell
Differential Revision: https://phabricator.services.mozilla.com/D96812
This commit is contained in:
Родитель
9b9b55b106
Коммит
cee7e57c4c
|
@ -1207,7 +1207,7 @@ void CompilationInput::trace(JSTracer* trc) {
|
||||||
TraceNullableRoot(trc, &enclosingScope, "compilation-input-enclosing-scope");
|
TraceNullableRoot(trc, &enclosingScope, "compilation-input-enclosing-scope");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilationAtomCache::trace(JSTracer* trc) { atoms.trace(trc); }
|
void CompilationAtomCache::trace(JSTracer* trc) { atoms_.trace(trc); }
|
||||||
|
|
||||||
void CompilationInfo::trace(JSTracer* trc) { input.trace(trc); }
|
void CompilationInfo::trace(JSTracer* trc) { input.trace(trc); }
|
||||||
|
|
||||||
|
|
|
@ -93,12 +93,20 @@ struct ScopeContext {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompilationAtomCache {
|
struct CompilationAtomCache {
|
||||||
|
private:
|
||||||
// Atoms lowered into or converted from CompilationStencil.parserAtomData.
|
// Atoms lowered into or converted from CompilationStencil.parserAtomData.
|
||||||
//
|
//
|
||||||
// This field is here instead of in CompilationGCOutput because atoms lowered
|
// This field is here instead of in CompilationGCOutput because atoms lowered
|
||||||
// from JSAtom is part of input (enclosing scope bindings, lazy function name,
|
// from JSAtom is part of input (enclosing scope bindings, lazy function name,
|
||||||
// etc), and having 2 vectors in both input/output is error prone.
|
// etc), and having 2 vectors in both input/output is error prone.
|
||||||
JS::GCVector<JSAtom*, 0, js::SystemAllocPolicy> atoms;
|
JS::GCVector<JSAtom*, 0, js::SystemAllocPolicy> atoms_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JSAtom* getExistingAtomAt(ParserAtomIndex index) const;
|
||||||
|
JSAtom* getAtomAt(ParserAtomIndex index) const;
|
||||||
|
bool hasAtomAt(ParserAtomIndex index) const;
|
||||||
|
bool setAtomAt(JSContext* cx, ParserAtomIndex index, JSAtom* atom);
|
||||||
|
bool allocate(JSContext* cx, size_t length);
|
||||||
|
|
||||||
void trace(JSTracer* trc);
|
void trace(JSTracer* trc);
|
||||||
} JS_HAZ_GC_POINTER;
|
} JS_HAZ_GC_POINTER;
|
||||||
|
@ -252,6 +260,8 @@ struct CompilationStencil {
|
||||||
asmJS;
|
asmJS;
|
||||||
|
|
||||||
// List of parser atoms for this compilation.
|
// List of parser atoms for this compilation.
|
||||||
|
// This may contain nullptr entries when round-tripping with XDR if the atom
|
||||||
|
// was generated in original parse but not used by stencil.
|
||||||
ParserAtomVector parserAtomData;
|
ParserAtomVector parserAtomData;
|
||||||
|
|
||||||
// Parameterized chunk size to use for LifoAlloc.
|
// Parameterized chunk size to use for LifoAlloc.
|
||||||
|
|
|
@ -216,8 +216,13 @@ bool ParserAtomEntry::isIndex(uint32_t* indexp) const {
|
||||||
JSAtom* ParserAtomEntry::toJSAtom(JSContext* cx,
|
JSAtom* ParserAtomEntry::toJSAtom(JSContext* cx,
|
||||||
CompilationAtomCache& atomCache) const {
|
CompilationAtomCache& atomCache) const {
|
||||||
switch (atomIndexKind_) {
|
switch (atomIndexKind_) {
|
||||||
case AtomIndexKind::AtomIndex:
|
case AtomIndexKind::ParserAtomIndex: {
|
||||||
return atomCache.atoms[atomIndex_];
|
JSAtom* atom = atomCache.getAtomAt(toParserAtomIndex());
|
||||||
|
if (atom) {
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case AtomIndexKind::WellKnown:
|
case AtomIndexKind::WellKnown:
|
||||||
return GetWellKnownAtom(cx, WellKnownAtomId(atomIndex_));
|
return GetWellKnownAtom(cx, WellKnownAtomId(atomIndex_));
|
||||||
|
@ -229,9 +234,6 @@ JSAtom* ParserAtomEntry::toJSAtom(JSContext* cx,
|
||||||
|
|
||||||
case AtomIndexKind::Static2:
|
case AtomIndexKind::Static2:
|
||||||
return cx->staticStrings().getLength2FromIndex(atomIndex_);
|
return cx->staticStrings().getLength2FromIndex(atomIndex_);
|
||||||
|
|
||||||
case AtomIndexKind::NotInstantiated:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return instantiate(cx, atomCache);
|
return instantiate(cx, atomCache);
|
||||||
|
@ -240,8 +242,11 @@ JSAtom* ParserAtomEntry::toJSAtom(JSContext* cx,
|
||||||
JSAtom* ParserAtomEntry::toExistingJSAtom(
|
JSAtom* ParserAtomEntry::toExistingJSAtom(
|
||||||
JSContext* cx, CompilationAtomCache& atomCache) const {
|
JSContext* cx, CompilationAtomCache& atomCache) const {
|
||||||
switch (atomIndexKind_) {
|
switch (atomIndexKind_) {
|
||||||
case AtomIndexKind::AtomIndex:
|
case AtomIndexKind::ParserAtomIndex: {
|
||||||
return atomCache.atoms[atomIndex_];
|
JSAtom* atom = atomCache.getExistingAtomAt(toParserAtomIndex());
|
||||||
|
MOZ_ASSERT(atom);
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
|
||||||
case AtomIndexKind::WellKnown:
|
case AtomIndexKind::WellKnown:
|
||||||
return GetWellKnownAtom(cx, WellKnownAtomId(atomIndex_));
|
return GetWellKnownAtom(cx, WellKnownAtomId(atomIndex_));
|
||||||
|
@ -253,9 +258,6 @@ JSAtom* ParserAtomEntry::toExistingJSAtom(
|
||||||
|
|
||||||
case AtomIndexKind::Static2:
|
case AtomIndexKind::Static2:
|
||||||
return cx->staticStrings().getLength2FromIndex(atomIndex_);
|
return cx->staticStrings().getLength2FromIndex(atomIndex_);
|
||||||
|
|
||||||
case AtomIndexKind::NotInstantiated:
|
|
||||||
MOZ_CRASH("ParserAtom should already be instantiated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -263,8 +265,6 @@ JSAtom* ParserAtomEntry::toExistingJSAtom(
|
||||||
|
|
||||||
JSAtom* ParserAtomEntry::instantiate(JSContext* cx,
|
JSAtom* ParserAtomEntry::instantiate(JSContext* cx,
|
||||||
CompilationAtomCache& atomCache) const {
|
CompilationAtomCache& atomCache) const {
|
||||||
MOZ_ASSERT(isNotInstantiated());
|
|
||||||
|
|
||||||
JSAtom* atom;
|
JSAtom* atom;
|
||||||
if (hasLatin1Chars()) {
|
if (hasLatin1Chars()) {
|
||||||
atom = AtomizeChars(cx, hash(), latin1Chars(), length());
|
atom = AtomizeChars(cx, hash(), latin1Chars(), length());
|
||||||
|
@ -275,17 +275,10 @@ JSAtom* ParserAtomEntry::instantiate(JSContext* cx,
|
||||||
js::ReportOutOfMemory(cx);
|
js::ReportOutOfMemory(cx);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto index = atomCache.atoms.length();
|
if (!atomCache.setAtomAt(cx, toParserAtomIndex(), atom)) {
|
||||||
|
|
||||||
// This cannot be infallibleAppend because there are toJSAtom consumers that
|
|
||||||
// doesn't reserve CompilationAtomCache.atoms beforehand
|
|
||||||
if (!atomCache.atoms.append(atom)) {
|
|
||||||
js::ReportOutOfMemory(cx);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const_cast<ParserAtomEntry*>(this)->setAtomIndex(AtomIndex(index));
|
|
||||||
|
|
||||||
return atom;
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +321,7 @@ JS::Result<const ParserAtom*, OOM> ParserAtomsTable::addEntry(
|
||||||
if (!entries_.append(entry)) {
|
if (!entries_.append(entry)) {
|
||||||
return RaiseParserAtomsOOMError(cx);
|
return RaiseParserAtomsOOMError(cx);
|
||||||
}
|
}
|
||||||
|
entry->setParserAtomIndex(index);
|
||||||
if (!entryMap_.add(addPtr, entry, index)) {
|
if (!entryMap_.add(addPtr, entry, index)) {
|
||||||
return RaiseParserAtomsOOMError(cx);
|
return RaiseParserAtomsOOMError(cx);
|
||||||
}
|
}
|
||||||
|
@ -385,27 +379,27 @@ ParserAtomVectorBuilder::ParserAtomVectorBuilder(JSRuntime* rt,
|
||||||
alloc_(&alloc),
|
alloc_(&alloc),
|
||||||
entries_(entries) {}
|
entries_(entries) {}
|
||||||
|
|
||||||
bool ParserAtomVectorBuilder::reserve(JSContext* cx, size_t count) {
|
bool ParserAtomVectorBuilder::resize(JSContext* cx, size_t count) {
|
||||||
if (count >= TaggedParserAtomIndex::IndexLimit) {
|
if (count >= TaggedParserAtomIndex::IndexLimit) {
|
||||||
ReportAllocationOverflow(cx);
|
ReportAllocationOverflow(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!entries_.reserve(count)) {
|
if (!entries_.resize(count)) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internLatin1(
|
JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internLatin1At(
|
||||||
JSContext* cx, const Latin1Char* latin1Ptr, HashNumber hash,
|
JSContext* cx, const Latin1Char* latin1Ptr, HashNumber hash,
|
||||||
uint32_t length) {
|
uint32_t length, ParserAtomIndex index) {
|
||||||
return intern<Latin1Char, Latin1Char>(cx, latin1Ptr, hash, length);
|
return internAt<Latin1Char, Latin1Char>(cx, latin1Ptr, hash, length, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internChar16(
|
JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internChar16At(
|
||||||
JSContext* cx, LittleEndianChars twoByteLE, HashNumber hash,
|
JSContext* cx, LittleEndianChars twoByteLE, HashNumber hash,
|
||||||
uint32_t length) {
|
uint32_t length, ParserAtomIndex index) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
InflatedChar16Sequence<LittleEndianChars> seq(twoByteLE, length);
|
InflatedChar16Sequence<LittleEndianChars> seq(twoByteLE, length);
|
||||||
bool wide = false;
|
bool wide = false;
|
||||||
|
@ -419,12 +413,14 @@ JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internChar16(
|
||||||
MOZ_ASSERT(wide);
|
MOZ_ASSERT(wide);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return intern<char16_t, LittleEndianChars>(cx, twoByteLE, hash, length);
|
return internAt<char16_t, LittleEndianChars>(cx, twoByteLE, hash, length,
|
||||||
|
index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharT, typename SeqCharT, typename InputCharsT>
|
template <typename CharT, typename SeqCharT, typename InputCharsT>
|
||||||
JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::intern(
|
JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::internAt(
|
||||||
JSContext* cx, InputCharsT chars, HashNumber hash, uint32_t length) {
|
JSContext* cx, InputCharsT chars, HashNumber hash, uint32_t length,
|
||||||
|
ParserAtomIndex index) {
|
||||||
InflatedChar16Sequence<SeqCharT> seq(chars, length);
|
InflatedChar16Sequence<SeqCharT> seq(chars, length);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -437,9 +433,9 @@ JS::Result<const ParserAtom*, OOM> ParserAtomVectorBuilder::intern(
|
||||||
ParserAtomEntry* entry;
|
ParserAtomEntry* entry;
|
||||||
MOZ_TRY_VAR(entry,
|
MOZ_TRY_VAR(entry,
|
||||||
ParserAtomEntry::allocate<CharT>(cx, *alloc_, seq, length, hash));
|
ParserAtomEntry::allocate<CharT>(cx, *alloc_, seq, length, hash));
|
||||||
if (!entries_.append(entry)) {
|
entry->setParserAtomIndex(index);
|
||||||
return RaiseParserAtomsOOMError(cx);
|
entries_[index] = entry;
|
||||||
}
|
|
||||||
return entry->asAtom();
|
return entry->asAtom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +529,7 @@ JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internChar16(
|
||||||
|
|
||||||
JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internJSAtom(
|
JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internJSAtom(
|
||||||
JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom) {
|
JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom) {
|
||||||
const ParserAtom* id;
|
const ParserAtom* parserAtom;
|
||||||
{
|
{
|
||||||
JS::AutoCheckCannotGC nogc;
|
JS::AutoCheckCannotGC nogc;
|
||||||
|
|
||||||
|
@ -544,24 +540,24 @@ JS::Result<const ParserAtom*, OOM> ParserAtomsTable::internJSAtom(
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
id = result.unwrap();
|
parserAtom = result.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id->isNotInstantiated()) {
|
if (parserAtom->isParserAtomIndex()) {
|
||||||
MOZ_ASSERT(id->equalsJSAtom(atom));
|
ParserAtomIndex index = parserAtom->toParserAtomIndex();
|
||||||
|
auto& atomCache = compilationInfo.input.atomCache;
|
||||||
|
|
||||||
auto index = AtomIndex(compilationInfo.input.atomCache.atoms.length());
|
if (!atomCache.hasAtomAt(index)) {
|
||||||
if (!compilationInfo.input.atomCache.atoms.append(atom)) {
|
if (!atomCache.setAtomAt(cx, index, atom)) {
|
||||||
return RaiseParserAtomsOOMError(cx);
|
return mozilla::Err(PARSER_ATOMS_OOM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const_cast<ParserAtom*>(id)->setAtomIndex(AtomIndex(index));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should (infallibly) map back to the same JSAtom.
|
// We should (infallibly) map back to the same JSAtom.
|
||||||
MOZ_ASSERT(id->toJSAtom(cx, compilationInfo.input.atomCache) == atom);
|
MOZ_ASSERT(parserAtom->toJSAtom(cx, compilationInfo.input.atomCache) == atom);
|
||||||
|
|
||||||
return id;
|
return parserAtom;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Result<const ParserAtom*, OOM> ParserAtomsTable::concatAtoms(
|
JS::Result<const ParserAtom*, OOM> ParserAtomsTable::concatAtoms(
|
||||||
|
@ -643,20 +639,14 @@ const ParserAtom* ParserAtomVectorBuilder::getStatic2(
|
||||||
return WellKnownParserAtoms::rom_.length2Table[size_t(s)].asAtom();
|
return WellKnownParserAtoms::rom_.length2Table[size_t(s)].asAtom();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RequiredNonStaticAtomCount(const ParserAtomVector& entries) {
|
|
||||||
size_t count = 0;
|
|
||||||
for (const auto& entry : entries) {
|
|
||||||
if (entry->isUsedByStencil() || entry->isAtomIndex()) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InstantiateMarkedAtoms(JSContext* cx, const ParserAtomVector& entries,
|
bool InstantiateMarkedAtoms(JSContext* cx, const ParserAtomVector& entries,
|
||||||
CompilationAtomCache& atomCache) {
|
CompilationAtomCache& atomCache) {
|
||||||
for (const auto& entry : entries) {
|
for (const auto& entry : entries) {
|
||||||
if (entry->isUsedByStencil() && entry->isNotInstantiated()) {
|
if (!entry) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (entry->isUsedByStencil() && entry->isParserAtomIndex() &&
|
||||||
|
!atomCache.hasAtomAt(entry->toParserAtomIndex())) {
|
||||||
if (!entry->instantiate(cx, atomCache)) {
|
if (!entry->instantiate(cx, atomCache)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +808,8 @@ static XDRResult XDRParserAtomTaggedIndex(XDRState<mode>* xdr,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <XDRMode mode>
|
template <XDRMode mode>
|
||||||
XDRResult XDRParserAtomData(XDRState<mode>* xdr, const ParserAtom** atomp) {
|
XDRResult XDRParserAtomDataAt(XDRState<mode>* xdr, const ParserAtom** atomp,
|
||||||
|
ParserAtomIndex index) {
|
||||||
static_assert(JSString::MAX_LENGTH <= INT32_MAX,
|
static_assert(JSString::MAX_LENGTH <= INT32_MAX,
|
||||||
"String length must fit in 31 bits");
|
"String length must fit in 31 bits");
|
||||||
|
|
||||||
|
@ -865,14 +856,16 @@ XDRResult XDRParserAtomData(XDRState<mode>* xdr, const ParserAtom** atomp) {
|
||||||
MOZ_TRY(xdr->peekData(&ptr, length * sizeof(Latin1Char)));
|
MOZ_TRY(xdr->peekData(&ptr, length * sizeof(Latin1Char)));
|
||||||
chars = reinterpret_cast<const Latin1Char*>(ptr);
|
chars = reinterpret_cast<const Latin1Char*>(ptr);
|
||||||
}
|
}
|
||||||
mbAtom = xdr->frontendAtoms().internLatin1(cx, chars, hash, length);
|
mbAtom =
|
||||||
|
xdr->frontendAtoms().internLatin1At(cx, chars, hash, length, index);
|
||||||
} else {
|
} else {
|
||||||
const uint8_t* twoByteCharsLE = nullptr;
|
const uint8_t* twoByteCharsLE = nullptr;
|
||||||
if (length) {
|
if (length) {
|
||||||
MOZ_TRY(xdr->peekData(&twoByteCharsLE, length * sizeof(char16_t)));
|
MOZ_TRY(xdr->peekData(&twoByteCharsLE, length * sizeof(char16_t)));
|
||||||
}
|
}
|
||||||
LittleEndianChars leTwoByte(twoByteCharsLE);
|
LittleEndianChars leTwoByte(twoByteCharsLE);
|
||||||
mbAtom = xdr->frontendAtoms().internChar16(cx, leTwoByte, hash, length);
|
mbAtom =
|
||||||
|
xdr->frontendAtoms().internChar16At(cx, leTwoByte, hash, length, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ParserAtom* atom = mbAtom.unwrapOr(nullptr);
|
const ParserAtom* atom = mbAtom.unwrapOr(nullptr);
|
||||||
|
@ -888,16 +881,16 @@ XDRResult XDRParserAtomData(XDRState<mode>* xdr, const ParserAtom** atomp) {
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
template XDRResult XDRParserAtomData(XDRState<XDR_ENCODE>* xdr,
|
template XDRResult XDRParserAtomDataAt(XDRState<XDR_ENCODE>* xdr,
|
||||||
const ParserAtom** atomp);
|
const ParserAtom** atomp,
|
||||||
template XDRResult XDRParserAtomData(XDRState<XDR_DECODE>* xdr,
|
ParserAtomIndex index);
|
||||||
const ParserAtom** atomp);
|
template XDRResult XDRParserAtomDataAt(XDRState<XDR_DECODE>* xdr,
|
||||||
|
const ParserAtom** atomp,
|
||||||
|
ParserAtomIndex index);
|
||||||
|
|
||||||
template <XDRMode mode>
|
template <XDRMode mode>
|
||||||
XDRResult XDRParserAtom(XDRState<mode>* xdr, const ParserAtom** atomp) {
|
XDRResult XDRParserAtom(XDRState<mode>* xdr, const ParserAtom** atomp) {
|
||||||
if (mode == XDR_ENCODE) {
|
if (mode == XDR_ENCODE) {
|
||||||
MOZ_ASSERT(xdr->hasAtomMap());
|
|
||||||
|
|
||||||
uint32_t atomIndex;
|
uint32_t atomIndex;
|
||||||
ParserAtomTag tag = ParserAtomTag::Normal;
|
ParserAtomTag tag = ParserAtomTag::Normal;
|
||||||
if ((*atomp)->isWellKnownAtomId()) {
|
if ((*atomp)->isWellKnownAtomId()) {
|
||||||
|
@ -910,14 +903,7 @@ XDRResult XDRParserAtom(XDRState<mode>* xdr, const ParserAtom** atomp) {
|
||||||
atomIndex = uint32_t((*atomp)->toStaticParserString2());
|
atomIndex = uint32_t((*atomp)->toStaticParserString2());
|
||||||
tag = ParserAtomTag::Static2;
|
tag = ParserAtomTag::Static2;
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT((*atomp)->isNotInstantiated() || (*atomp)->isAtomIndex());
|
atomIndex = uint32_t((*atomp)->toParserAtomIndex());
|
||||||
MOZ_ASSERT((*atomp)->isUsedByStencil());
|
|
||||||
|
|
||||||
// Either AtomIndexKind::NotInstantiated or AtomIndexKind::AtomIndex.
|
|
||||||
// References to atoms are encoded as indices into the atom stream.
|
|
||||||
XDRParserAtomMap::Ptr p = xdr->parserAtomMap().lookup(*atomp);
|
|
||||||
MOZ_ASSERT(p);
|
|
||||||
atomIndex = p->value();
|
|
||||||
tag = ParserAtomTag::Normal;
|
tag = ParserAtomTag::Normal;
|
||||||
}
|
}
|
||||||
MOZ_TRY(XDRParserAtomTaggedIndex(xdr, &tag, &atomIndex));
|
MOZ_TRY(XDRParserAtomTaggedIndex(xdr, &tag, &atomIndex));
|
||||||
|
|
|
@ -35,10 +35,6 @@ class ParserAtomsTable;
|
||||||
|
|
||||||
mozilla::GenericErrorResult<OOM> RaiseParserAtomsOOMError(JSContext* cx);
|
mozilla::GenericErrorResult<OOM> RaiseParserAtomsOOMError(JSContext* cx);
|
||||||
|
|
||||||
// An index into CompilationAtomCache.
|
|
||||||
// This is local to the current compilation.
|
|
||||||
using AtomIndex = TypedIndex<JSAtom*>;
|
|
||||||
|
|
||||||
// An index to map WellKnownParserAtoms to cx->names().
|
// An index to map WellKnownParserAtoms to cx->names().
|
||||||
// This is consistent across multiple compilation.
|
// This is consistent across multiple compilation.
|
||||||
//
|
//
|
||||||
|
@ -209,10 +205,8 @@ class alignas(alignof(uint32_t)) ParserAtomEntry {
|
||||||
|
|
||||||
// Mapping into from ParserAtoms to JSAtoms.
|
// Mapping into from ParserAtoms to JSAtoms.
|
||||||
enum class AtomIndexKind : uint8_t {
|
enum class AtomIndexKind : uint8_t {
|
||||||
// Not yet instantiated
|
// Index into CompilationStencil.parserAtomData.
|
||||||
NotInstantiated,
|
ParserAtomIndex,
|
||||||
// Index into CompilationAtomCache
|
|
||||||
AtomIndex,
|
|
||||||
// WellKnownAtomId to index into cx->names() set
|
// WellKnownAtomId to index into cx->names() set
|
||||||
WellKnown,
|
WellKnown,
|
||||||
// Index into StaticStrings length-1 set
|
// Index into StaticStrings length-1 set
|
||||||
|
@ -221,12 +215,12 @@ class alignas(alignof(uint32_t)) ParserAtomEntry {
|
||||||
Static2,
|
Static2,
|
||||||
};
|
};
|
||||||
uint32_t atomIndex_ = 0;
|
uint32_t atomIndex_ = 0;
|
||||||
AtomIndexKind atomIndexKind_ = AtomIndexKind::NotInstantiated;
|
AtomIndexKind atomIndexKind_ = AtomIndexKind::ParserAtomIndex;
|
||||||
|
|
||||||
// Encoding type.
|
// Encoding type.
|
||||||
bool hasTwoByteChars_ = false;
|
bool hasTwoByteChars_ = false;
|
||||||
|
|
||||||
// Other flags.
|
// Mutable flags.
|
||||||
bool usedByStencil_ = false;
|
bool usedByStencil_ = false;
|
||||||
|
|
||||||
// End of fields.
|
// End of fields.
|
||||||
|
@ -304,13 +298,9 @@ class alignas(alignof(uint32_t)) ParserAtomEntry {
|
||||||
HashNumber hash() const { return hash_; }
|
HashNumber hash() const { return hash_; }
|
||||||
uint32_t length() const { return length_; }
|
uint32_t length() const { return length_; }
|
||||||
|
|
||||||
bool isNotInstantiated() const {
|
|
||||||
return atomIndexKind_ == AtomIndexKind::NotInstantiated;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUsedByStencil() const { return usedByStencil_; }
|
bool isUsedByStencil() const { return usedByStencil_; }
|
||||||
void markUsedByStencil() const {
|
void markUsedByStencil() const {
|
||||||
if ((isNotInstantiated() || isAtomIndex())) {
|
if (isParserAtomIndex()) {
|
||||||
// Use const method + const_cast here to avoid marking static strings'
|
// Use const method + const_cast here to avoid marking static strings'
|
||||||
// field mutable.
|
// field mutable.
|
||||||
const_cast<ParserAtomEntry*>(this)->usedByStencil_ = true;
|
const_cast<ParserAtomEntry*>(this)->usedByStencil_ = true;
|
||||||
|
@ -322,6 +312,10 @@ class alignas(alignof(uint32_t)) ParserAtomEntry {
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
bool equalsSeq(HashNumber hash, InflatedChar16Sequence<CharT> seq) const;
|
bool equalsSeq(HashNumber hash, InflatedChar16Sequence<CharT> seq) const;
|
||||||
|
|
||||||
|
ParserAtomIndex toParserAtomIndex() const {
|
||||||
|
MOZ_ASSERT(isParserAtomIndex());
|
||||||
|
return ParserAtomIndex(atomIndex_);
|
||||||
|
}
|
||||||
WellKnownAtomId toWellKnownAtomId() const {
|
WellKnownAtomId toWellKnownAtomId() const {
|
||||||
MOZ_ASSERT(isWellKnownAtomId());
|
MOZ_ASSERT(isWellKnownAtomId());
|
||||||
return WellKnownAtomId(atomIndex_);
|
return WellKnownAtomId(atomIndex_);
|
||||||
|
@ -335,8 +329,8 @@ class alignas(alignof(uint32_t)) ParserAtomEntry {
|
||||||
return StaticParserString2(atomIndex_);
|
return StaticParserString2(atomIndex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAtomIndex() const {
|
bool isParserAtomIndex() const {
|
||||||
return atomIndexKind_ == AtomIndexKind::AtomIndex;
|
return atomIndexKind_ == AtomIndexKind::ParserAtomIndex;
|
||||||
}
|
}
|
||||||
bool isWellKnownAtomId() const {
|
bool isWellKnownAtomId() const {
|
||||||
return atomIndexKind_ == AtomIndexKind::WellKnown;
|
return atomIndexKind_ == AtomIndexKind::WellKnown;
|
||||||
|
@ -348,11 +342,12 @@ class alignas(alignof(uint32_t)) ParserAtomEntry {
|
||||||
return atomIndexKind_ == AtomIndexKind::Static2;
|
return atomIndexKind_ == AtomIndexKind::Static2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void setParserAtomIndex(ParserAtomIndex index) {
|
||||||
void setAtomIndex(AtomIndex index) {
|
|
||||||
atomIndex_ = index;
|
atomIndex_ = index;
|
||||||
atomIndexKind_ = AtomIndexKind::AtomIndex;
|
atomIndexKind_ = AtomIndexKind::ParserAtomIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
constexpr void setWellKnownAtomId(WellKnownAtomId atomId) {
|
constexpr void setWellKnownAtomId(WellKnownAtomId atomId) {
|
||||||
atomIndex_ = static_cast<uint32_t>(atomId);
|
atomIndex_ = static_cast<uint32_t>(atomId);
|
||||||
atomIndexKind_ = AtomIndexKind::WellKnown;
|
atomIndexKind_ = AtomIndexKind::WellKnown;
|
||||||
|
@ -648,10 +643,6 @@ class WellKnownParserAtoms {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The number of atoms with either usedByStencil or AtomIndex,
|
|
||||||
// that requires space in CompilationAtomCache.atoms during instantiation.
|
|
||||||
size_t RequiredNonStaticAtomCount(const ParserAtomVector& entries);
|
|
||||||
|
|
||||||
bool InstantiateMarkedAtoms(JSContext* cx, const ParserAtomVector& entries,
|
bool InstantiateMarkedAtoms(JSContext* cx, const ParserAtomVector& entries,
|
||||||
CompilationAtomCache& atomCache);
|
CompilationAtomCache& atomCache);
|
||||||
|
|
||||||
|
@ -723,22 +714,23 @@ class ParserAtomVectorBuilder {
|
||||||
ParserAtomVectorBuilder(JSRuntime* rt, LifoAlloc& alloc,
|
ParserAtomVectorBuilder(JSRuntime* rt, LifoAlloc& alloc,
|
||||||
ParserAtomVector& entries);
|
ParserAtomVector& entries);
|
||||||
|
|
||||||
bool reserve(JSContext* cx, size_t count);
|
bool resize(JSContext* cx, size_t count);
|
||||||
size_t length() const { return entries_.length(); }
|
size_t length() const { return entries_.length(); }
|
||||||
ParserAtom* get(size_t index) { return entries_[index]->asAtom(); }
|
ParserAtom* get(size_t index) { return entries_[index]->asAtom(); }
|
||||||
|
|
||||||
JS::Result<const ParserAtom*, OOM> internLatin1(
|
JS::Result<const ParserAtom*, OOM> internLatin1At(
|
||||||
JSContext* cx, const JS::Latin1Char* latin1Ptr, HashNumber hash,
|
JSContext* cx, const JS::Latin1Char* latin1Ptr, HashNumber hash,
|
||||||
uint32_t length);
|
uint32_t length, ParserAtomIndex index);
|
||||||
|
|
||||||
JS::Result<const ParserAtom*, OOM> internChar16(
|
JS::Result<const ParserAtom*, OOM> internChar16At(
|
||||||
JSContext* cx, const LittleEndianChars twoByteLE, HashNumber hash,
|
JSContext* cx, const LittleEndianChars twoByteLE, HashNumber hash,
|
||||||
uint32_t length);
|
uint32_t length, ParserAtomIndex index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename CharT, typename SeqCharT, typename InputCharsT>
|
template <typename CharT, typename SeqCharT, typename InputCharsT>
|
||||||
JS::Result<const ParserAtom*, OOM> intern(JSContext* cx, InputCharsT chars,
|
JS::Result<const ParserAtom*, OOM> internAt(JSContext* cx, InputCharsT chars,
|
||||||
HashNumber hash, uint32_t length);
|
HashNumber hash, uint32_t length,
|
||||||
|
ParserAtomIndex index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const ParserAtom* getWellKnown(WellKnownAtomId atomId) const;
|
const ParserAtom* getWellKnown(WellKnownAtomId atomId) const;
|
||||||
|
|
|
@ -799,9 +799,7 @@ bool CompilationInfoVector::instantiateStencilsAfterPreparation(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilationInfo::prepareInputAndStencilForInstantiate(JSContext* cx) {
|
bool CompilationInfo::prepareInputAndStencilForInstantiate(JSContext* cx) {
|
||||||
if (!input.atomCache.atoms.reserve(
|
if (!input.atomCache.allocate(cx, stencil.parserAtomData.length())) {
|
||||||
RequiredNonStaticAtomCount(stencil.parserAtomData))) {
|
|
||||||
ReportOutOfMemory(cx);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1583,3 +1581,51 @@ mozilla::Span<ScriptThingVariant> js::frontend::NewScriptThingSpanUninitialized(
|
||||||
|
|
||||||
return mozilla::Span<ScriptThingVariant>(stencilThings, ngcthings);
|
return mozilla::Span<ScriptThingVariant>(stencilThings, ngcthings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSAtom* CompilationAtomCache::getExistingAtomAt(ParserAtomIndex index) const {
|
||||||
|
return atoms_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
JSAtom* CompilationAtomCache::getAtomAt(ParserAtomIndex index) const {
|
||||||
|
if (size_t(index) >= atoms_.length()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return atoms_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompilationAtomCache::hasAtomAt(ParserAtomIndex index) const {
|
||||||
|
if (size_t(index) >= atoms_.length()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !!atoms_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompilationAtomCache::setAtomAt(JSContext* cx, ParserAtomIndex index,
|
||||||
|
JSAtom* atom) {
|
||||||
|
if (size_t(index) < atoms_.length()) {
|
||||||
|
atoms_[index] = atom;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!atoms_.resize(size_t(index) + 1)) {
|
||||||
|
ReportOutOfMemory(cx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
atoms_[index] = atom;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompilationAtomCache::allocate(JSContext* cx, size_t length) {
|
||||||
|
MOZ_ASSERT(length >= atoms_.length());
|
||||||
|
if (length == atoms_.length()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!atoms_.resize(length)) {
|
||||||
|
ReportOutOfMemory(cx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -305,45 +305,52 @@ template <XDRMode mode>
|
||||||
static XDRResult ParserAtomTable(XDRState<mode>* xdr,
|
static XDRResult ParserAtomTable(XDRState<mode>* xdr,
|
||||||
frontend::CompilationStencil& stencil) {
|
frontend::CompilationStencil& stencil) {
|
||||||
if (mode == XDR_ENCODE) {
|
if (mode == XDR_ENCODE) {
|
||||||
|
uint32_t atomVectorLength = stencil.parserAtomData.length();
|
||||||
|
MOZ_TRY(XDRAtomCount(xdr, &atomVectorLength));
|
||||||
|
|
||||||
uint32_t atomCount = 0;
|
uint32_t atomCount = 0;
|
||||||
for (const auto& entry : stencil.parserAtomData) {
|
for (const auto& entry : stencil.parserAtomData) {
|
||||||
|
if (!entry) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (entry->isUsedByStencil()) {
|
if (entry->isUsedByStencil()) {
|
||||||
atomCount++;
|
atomCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
||||||
|
|
||||||
if (!xdr->parserAtomMap().reserve(atomCount)) {
|
|
||||||
return xdr->fail(JS::TranscodeResult_Throw);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t index = 0;
|
|
||||||
|
|
||||||
for (const auto& entry : stencil.parserAtomData) {
|
for (const auto& entry : stencil.parserAtomData) {
|
||||||
|
if (!entry) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (entry->isUsedByStencil()) {
|
if (entry->isUsedByStencil()) {
|
||||||
const frontend::ParserAtom* atom = entry->asAtom();
|
const frontend::ParserAtom* atom = entry->asAtom();
|
||||||
MOZ_TRY(XDRParserAtomData(xdr, &atom));
|
uint32_t index = atom->toParserAtomIndex();
|
||||||
|
MOZ_TRY(xdr->codeUint32(&index));
|
||||||
xdr->parserAtomMap().putNewInfallible(atom, index);
|
MOZ_TRY(
|
||||||
index++;
|
XDRParserAtomDataAt(xdr, &atom, frontend::ParserAtomIndex(index)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t atomVectorLength;
|
||||||
|
MOZ_TRY(XDRAtomCount(xdr, &atomVectorLength));
|
||||||
|
|
||||||
|
if (!xdr->frontendAtoms().resize(xdr->cx(), atomVectorLength)) {
|
||||||
|
return xdr->fail(JS::TranscodeResult_Throw);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t atomCount;
|
uint32_t atomCount;
|
||||||
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
MOZ_TRY(XDRAtomCount(xdr, &atomCount));
|
||||||
MOZ_ASSERT(!xdr->hasAtomTable());
|
MOZ_ASSERT(!xdr->hasAtomTable());
|
||||||
|
|
||||||
if (!xdr->frontendAtoms().reserve(xdr->cx(), atomCount)) {
|
|
||||||
return xdr->fail(JS::TranscodeResult_Throw);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < atomCount; i++) {
|
for (uint32_t i = 0; i < atomCount; i++) {
|
||||||
const frontend::ParserAtom* atom = nullptr;
|
const frontend::ParserAtom* atom = nullptr;
|
||||||
MOZ_TRY(XDRParserAtomData(xdr, &atom));
|
uint32_t index;
|
||||||
|
MOZ_TRY(xdr->codeUint32(&index));
|
||||||
|
MOZ_TRY(XDRParserAtomDataAt(xdr, &atom, frontend::ParserAtomIndex(index)));
|
||||||
}
|
}
|
||||||
xdr->finishAtomTable();
|
xdr->finishAtomTable();
|
||||||
|
|
||||||
|
@ -457,7 +464,6 @@ XDRResult XDRState<mode>::codeStencil(
|
||||||
|
|
||||||
MOZ_ASSERT(isMainBuf());
|
MOZ_ASSERT(isMainBuf());
|
||||||
MOZ_TRY(XDRCompilationStencil(this, compilationInfo.stencil));
|
MOZ_TRY(XDRCompilationStencil(this, compilationInfo.stencil));
|
||||||
MOZ_TRY(finishChunk());
|
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
@ -478,7 +484,6 @@ XDRResult XDRState<mode>::codeFunctionStencil(
|
||||||
MOZ_TRY(ParserAtomTable(this, stencil));
|
MOZ_TRY(ParserAtomTable(this, stencil));
|
||||||
|
|
||||||
MOZ_TRY(XDRCompilationStencil(this, stencil));
|
MOZ_TRY(XDRCompilationStencil(this, stencil));
|
||||||
MOZ_TRY(finishChunk());
|
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
@ -709,12 +714,6 @@ XDRResult XDRIncrementalEncoder::linearize(JS::TranscodeBuffer& buffer) {
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
XDRResult XDRIncrementalStencilEncoder::finishChunk() {
|
|
||||||
parserAtomMap_.clear();
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
XDRResult XDRIncrementalStencilEncoder::linearize(JS::TranscodeBuffer& buffer) {
|
XDRResult XDRIncrementalStencilEncoder::linearize(JS::TranscodeBuffer& buffer) {
|
||||||
switchToHeaderBuf();
|
switchToHeaderBuf();
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,6 @@ using XDRResult = XDRResultT<mozilla::Ok>;
|
||||||
using XDRAtomTable = JS::GCVector<PreBarriered<JSAtom*>>;
|
using XDRAtomTable = JS::GCVector<PreBarriered<JSAtom*>>;
|
||||||
using XDRAtomMap = JS::GCHashMap<PreBarriered<JSAtom*>, uint32_t>;
|
using XDRAtomMap = JS::GCHashMap<PreBarriered<JSAtom*>, uint32_t>;
|
||||||
|
|
||||||
using XDRParserAtomMap = HashMap<const frontend::ParserAtom*, uint32_t>;
|
|
||||||
|
|
||||||
class XDRBufferBase {
|
class XDRBufferBase {
|
||||||
public:
|
public:
|
||||||
explicit XDRBufferBase(JSContext* cx, size_t cursor = 0)
|
explicit XDRBufferBase(JSContext* cx, size_t cursor = 0)
|
||||||
|
@ -262,10 +260,6 @@ class XDRState : public XDRCoderBase {
|
||||||
|
|
||||||
virtual bool hasAtomMap() const { return false; }
|
virtual bool hasAtomMap() const { return false; }
|
||||||
virtual XDRAtomMap& atomMap() { MOZ_CRASH("does not have atomMap"); }
|
virtual XDRAtomMap& atomMap() { MOZ_CRASH("does not have atomMap"); }
|
||||||
virtual XDRParserAtomMap& parserAtomMap() {
|
|
||||||
// This accessor is only used when encoding stencils.
|
|
||||||
MOZ_CRASH("does not have parserAtomMap");
|
|
||||||
}
|
|
||||||
virtual uint32_t& natoms() { MOZ_CRASH("does not have atomMap."); }
|
virtual uint32_t& natoms() { MOZ_CRASH("does not have atomMap."); }
|
||||||
|
|
||||||
// The number of chunks (CompilationStencils) in the buffer.
|
// The number of chunks (CompilationStencils) in the buffer.
|
||||||
|
@ -287,7 +281,6 @@ class XDRState : public XDRCoderBase {
|
||||||
MOZ_CRASH("cannot switch to header buffer.");
|
MOZ_CRASH("cannot switch to header buffer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual XDRResult finishChunk() { return Ok(); }
|
|
||||||
virtual XDRResult codeDelazificationStencils(
|
virtual XDRResult codeDelazificationStencils(
|
||||||
frontend::CompilationInfoVector& compilationInfos) {
|
frontend::CompilationInfoVector& compilationInfos) {
|
||||||
MOZ_CRASH("cannot code delazification stencils.");
|
MOZ_CRASH("cannot code delazification stencils.");
|
||||||
|
@ -734,10 +727,6 @@ class XDRIncrementalStencilEncoder : public XDRIncrementalEncoderBase {
|
||||||
// b. atoms
|
// b. atoms
|
||||||
// c. CompilationStencil
|
// c. CompilationStencil
|
||||||
|
|
||||||
// Map from atoms to their index in the atom buffer
|
|
||||||
// Reset for each chunk.
|
|
||||||
XDRParserAtomMap parserAtomMap_;
|
|
||||||
|
|
||||||
using FunctionKey = uint64_t;
|
using FunctionKey = uint64_t;
|
||||||
static FunctionKey toFunctionKey(const SourceExtent& extent);
|
static FunctionKey toFunctionKey(const SourceExtent& extent);
|
||||||
|
|
||||||
|
@ -748,9 +737,7 @@ class XDRIncrementalStencilEncoder : public XDRIncrementalEncoderBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit XDRIncrementalStencilEncoder(JSContext* cx)
|
explicit XDRIncrementalStencilEncoder(JSContext* cx)
|
||||||
: XDRIncrementalEncoderBase(cx),
|
: XDRIncrementalEncoderBase(cx), encodedFunctions_(cx) {}
|
||||||
parserAtomMap_(cx),
|
|
||||||
encodedFunctions_(cx) {}
|
|
||||||
|
|
||||||
virtual ~XDRIncrementalStencilEncoder() = default;
|
virtual ~XDRIncrementalStencilEncoder() = default;
|
||||||
|
|
||||||
|
@ -759,11 +746,6 @@ class XDRIncrementalStencilEncoder : public XDRIncrementalEncoderBase {
|
||||||
|
|
||||||
bool isForStencil() const override { return true; }
|
bool isForStencil() const override { return true; }
|
||||||
|
|
||||||
bool hasAtomMap() const override { return true; }
|
|
||||||
XDRParserAtomMap& parserAtomMap() override { return parserAtomMap_; }
|
|
||||||
|
|
||||||
XDRResult finishChunk() override;
|
|
||||||
|
|
||||||
XDRResult linearize(JS::TranscodeBuffer& buffer) override;
|
XDRResult linearize(JS::TranscodeBuffer& buffer) override;
|
||||||
|
|
||||||
XDRResult codeStencils(frontend::CompilationInfoVector& compilationInfos);
|
XDRResult codeStencils(frontend::CompilationInfoVector& compilationInfos);
|
||||||
|
@ -783,8 +765,9 @@ XDRResult XDRParserAtom(XDRState<mode>* xdr,
|
||||||
const frontend::ParserAtom** atomp);
|
const frontend::ParserAtom** atomp);
|
||||||
|
|
||||||
template <XDRMode mode>
|
template <XDRMode mode>
|
||||||
XDRResult XDRParserAtomData(XDRState<mode>* xdr,
|
XDRResult XDRParserAtomDataAt(XDRState<mode>* xdr,
|
||||||
const frontend::ParserAtom** atomp);
|
const frontend::ParserAtom** atomp,
|
||||||
|
frontend::ParserAtomIndex index);
|
||||||
|
|
||||||
template <XDRMode mode>
|
template <XDRMode mode>
|
||||||
XDRResult XDRParserAtomOrNull(XDRState<mode>* xdr,
|
XDRResult XDRParserAtomOrNull(XDRState<mode>* xdr,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче