From d35f6aa3be00427ed0fa0027fd59fc7341c39241 Mon Sep 17 00:00:00 2001 From: Csoregi Natalia Date: Wed, 23 Sep 2020 05:21:54 +0300 Subject: [PATCH] Backed out 4 changesets (bug 1659104) for build bustages on StencilXdr.cpp. CLOSED TREE Backed out changeset 145c513b9bdd (bug 1659104) Backed out changeset 2019253fda44 (bug 1659104) Backed out changeset 55f980703773 (bug 1659104) Backed out changeset ffac61e233f7 (bug 1659104) --- js/src/builtin/TestingFunctions.cpp | 129 ---- js/src/frontend/CompilationInfo.h | 6 - js/src/frontend/ObjLiteral.h | 18 +- js/src/frontend/ParserAtom.cpp | 219 ------ js/src/frontend/ParserAtom.h | 28 +- js/src/frontend/Stencil.cpp | 69 +- js/src/frontend/Stencil.h | 21 +- js/src/frontend/StencilXdr.cpp | 920 -------------------------- js/src/frontend/StencilXdr.h | 40 -- js/src/frontend/moz.build | 1 - js/src/jsapi-tests/testParserAtom.cpp | 22 +- js/src/vm/JSScript.cpp | 9 +- js/src/vm/JSScript.h | 4 - js/src/vm/Scope.h | 2 +- js/src/vm/Xdr.cpp | 48 +- js/src/vm/Xdr.h | 105 --- 16 files changed, 33 insertions(+), 1608 deletions(-) delete mode 100644 js/src/frontend/StencilXdr.cpp delete mode 100644 js/src/frontend/StencilXdr.h diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 9980d0d39383..d06f7bb67b72 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -43,8 +43,6 @@ #ifdef DEBUG # include "frontend/TokenStream.h" #endif -#include "frontend/BytecodeCompilation.h" -#include "frontend/CompilationInfo.h" #include "gc/Allocator.h" #include "gc/Zone.h" #include "jit/BaselineJIT.h" @@ -102,7 +100,6 @@ #include "vm/PromiseObject.h" // js::PromiseObject, js::PromiseSlot_* #include "vm/ProxyObject.h" #include "vm/SavedStacks.h" -#include "vm/ScopeKind.h" #include "vm/Stack.h" #include "vm/StringType.h" #include "vm/TraceLogging.h" @@ -4875,122 +4872,6 @@ static bool SetLazyParsingDisabled(JSContext* cx, unsigned argc, Value* vp) { return true; } -static bool ParseAndDumpStencilXDR(JSContext* cx, uint32_t argc, Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - - if (!args.requireAtLeast(cx, "parseAndDumpStencilXDR", 1)) { - return false; - } - - RootedString src(cx, ToString(cx, args[0])); - if (!src) { - return false; - } - - const char* filename = "parseAndDumpStencilXDR-DATA.js"; - uint32_t lineno = 1; - - /* Linearize the string to obtain a char16_t* range. */ - AutoStableStringChars linearChars(cx); - if (!linearChars.initTwoByte(cx, src)) { - return false; - } - JS::SourceText srcBuf; - if (!srcBuf.init(cx, linearChars.twoByteChars(), src->length(), - JS::SourceOwnership::Borrowed)) { - return false; - } - - /* TODO: StencilXDR - Add option to select between full and syntax parse. */ - /* Compile the script text to stencil. */ - CompileOptions options(cx); - options.setFileAndLine(filename, lineno); - options.setForceFullParse(); - - Rooted compilationInfo( - cx, frontend::CompilationInfo(cx, options)); - if (!compilationInfo.get().input.initForGlobal(cx)) { - return false; - } - if (!frontend::CompileGlobalScriptToStencil(cx, compilationInfo.get(), srcBuf, - ScopeKind::Global)) { - return false; - } - - /* Serialize the stencil to XDR. */ - JS::TranscodeBuffer xdrBytes; - if (!compilationInfo.get().serializeStencils(cx, xdrBytes)) { - return false; - } - - /* Dump the bytes into a javascript ArrayBuffer and return a UInt8Array. */ - RootedObject arrayBuf(cx, JS::NewArrayBuffer(cx, xdrBytes.length())); - if (!arrayBuf) { - return false; - } - - { - JS::AutoAssertNoGC nogc; - bool isSharedMemory = false; - uint8_t* data = JS::GetArrayBufferData(arrayBuf, &isSharedMemory, nogc); - std::copy(xdrBytes.begin(), xdrBytes.end(), data); - } - - args.rval().setObject(*arrayBuf); - return true; -} - -static bool LoadFromStencilXDR(JSContext* cx, uint32_t argc, Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - - if (!args.requireAtLeast(cx, "loadFromStencilXDR", 1)) { - return false; - } - - /* Prepare the input byte array. */ - if (!args[0].isObject() || !args[0].toObject().is()) { - JS_ReportErrorASCII(cx, "loadFromStencilXDR: ArrayBuffer expected"); - return false; - } - RootedArrayBufferObject src(cx, &args[0].toObject().as()); - - const char* filename = "parseAndDumpStencilXDR-DATA.js"; - uint32_t lineno = 1; - - /* Prepare the CompilationInfo for decoding. */ - CompileOptions options(cx); - options.setFileAndLine(filename, lineno); - options.setForceFullParse(); - - Rooted compilationInfo( - cx, frontend::CompilationInfo(cx, options)); - if (!compilationInfo.get().input.initForGlobal(cx)) { - return false; - } - - /* Deserialize the stencil from XDR. */ - JS::TranscodeRange xdrRange(src->dataPointer(), src->byteLength()); - if (!compilationInfo.get().deserializeStencils(cx, xdrRange)) { - return false; - } - - /* Instantiate the stencil. */ - frontend::CompilationGCOutput output(cx); - if (!compilationInfo.get().instantiateStencils(cx, output)) { - return false; - } - - /* Obtain the JSScript, construct a scope chain, and evaluate it. */ - RootedScript script(cx, output.script); - RootedValue retVal(cx, UndefinedValue()); - if (!JS_ExecuteScript(cx, script, &retVal)) { - return false; - } - - args.rval().set(retVal); - return true; -} - static bool SetDiscardSource(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -7307,16 +7188,6 @@ JS_FN_HELP("setDefaultLocale", SetDefaultLocale, 1, 0, " An empty string or undefined resets the runtime locale to its default value.\n" " NOTE: The input string is not fully validated, it must be a valid BCP-47 language tag."), - JS_FN_HELP("parseAndDumpStencilXDR", ParseAndDumpStencilXDR, 1, 0, -"parseAndDumpStencilXDR(string)", -" Parses the given string argument as js script, produces the stencil" -" for it, and returns an ArrayBuf of the XDR-encoded contents."), - - JS_FN_HELP("loadFromStencilXDR", LoadFromStencilXDR, 1, 0, -"loadFromStencilXDR(arrayBuf)", -" Reads the given stencil XDR and executes the top-level script defined" -" within."), - JS_FS_HELP_END }; // clang-format on diff --git a/js/src/frontend/CompilationInfo.h b/js/src/frontend/CompilationInfo.h index f6369eda7d5a..20b3cbffe580 100644 --- a/js/src/frontend/CompilationInfo.h +++ b/js/src/frontend/CompilationInfo.h @@ -22,7 +22,6 @@ #include "js/HashTable.h" #include "js/RealmOptions.h" #include "js/SourceText.h" -#include "js/Transcoding.h" #include "js/Vector.h" #include "js/WasmModule.h" #include "vm/GlobalObject.h" // GlobalObject @@ -384,11 +383,6 @@ struct CompilationInfo { MOZ_MUST_USE bool instantiateStencils(JSContext* cx, CompilationGCOutput& gcOutput); - MOZ_MUST_USE bool serializeStencils(JSContext* cx, JS::TranscodeBuffer& buf, - bool* succeededOut = nullptr); - MOZ_MUST_USE bool deserializeStencils(JSContext* cx, - const JS::TranscodeRange& range, - bool* succeededOut = nullptr); JSAtom* liftParserAtomToJSAtom(JSContext* cx, const ParserAtom* parserAtom) { return parserAtom->toJSAtom(cx, *this).unwrapOr(nullptr); diff --git a/js/src/frontend/ObjLiteral.h b/js/src/frontend/ObjLiteral.h index 4ddf9315a9a7..31704fee339b 100644 --- a/js/src/frontend/ObjLiteral.h +++ b/js/src/frontend/ObjLiteral.h @@ -144,8 +144,7 @@ class JSONPrinter; namespace frontend { struct CompilationInfo; -class StencilXDR; -} // namespace frontend +} // Object-literal instruction opcodes. An object literal is constructed by a // straight-line sequence of these ops, each adding one property to the @@ -260,11 +259,8 @@ struct ObjLiteralWriterBase { static const uint32_t INDEXED_PROP = 0x00800000; static const int OP_SHIFT = 24; - public: - using CodeVector = Vector; - protected: - CodeVector code_; + Vector code_; public: ObjLiteralWriterBase() = default; @@ -323,13 +319,6 @@ struct ObjLiteralWriter : private ObjLiteralWriterBase { void clear() { code_.clear(); } - // For XDR decoding. - using CodeVector = typename ObjLiteralWriterBase::CodeVector; - void initializeForXDR(CodeVector&& code, uint8_t flags) { - code_ = std::move(code); - flags_.deserialize(flags); - } - mozilla::Span getCode() const { return code_; } ObjLiteralFlags getFlags() const { return flags_; } @@ -580,8 +569,7 @@ inline JSObject* InterpretObjLiteral(JSContext* cx, } class ObjLiteralStencil { - friend class frontend::StencilXDR; - + private: ObjLiteralWriter writer_; ObjLiteralAtomVector atoms_; diff --git a/js/src/frontend/ParserAtom.cpp b/js/src/frontend/ParserAtom.cpp index f57c58d05756..8a67777d2769 100644 --- a/js/src/frontend/ParserAtom.cpp +++ b/js/src/frontend/ParserAtom.cpp @@ -20,38 +20,6 @@ using namespace js; using namespace js::frontend; -namespace js { - -template <> -class InflatedChar16Sequence { - private: - LittleEndianChars chars_; - size_t idx_; - size_t len_; - - public: - InflatedChar16Sequence(LittleEndianChars chars, size_t length) - : chars_(chars), idx_(0), len_(length) {} - - bool hasMore() { return idx_ < len_; } - - char16_t next() { - MOZ_ASSERT(hasMore()); - return chars_[idx_++]; - } - - HashNumber computeHash() const { - auto copy = *this; - HashNumber hash = 0; - while (copy.hasMore()) { - hash = mozilla::AddToHash(hash, copy.next()); - } - return hash; - } -}; - -} // namespace js - namespace js { namespace frontend { @@ -356,42 +324,6 @@ JS::Result ParserAtomsTable::internLatin1( return internLatin1Seq(cx, addPtr, latin1Ptr, length); } -JS::Result ParserAtomsTable::internChar16LE( - JSContext* cx, LittleEndianChars twoByteLE, uint32_t length) { - // Check for tiny strings which are abundant in minified code. - if (const ParserAtom* tiny = wellKnownTable_.lookupTiny(twoByteLE, length)) { - return tiny; - } - - InflatedChar16Sequence seq(twoByteLE, length); - - // An XDR interning is guaranteed to be unique: there should be no - // existing atom with the same contents, except for well-known atoms. - // - // However, using the existing path which checks for exiting atoms - // is a lot simpler as it handles well-known atom checks seamlessly. - AddPtr addPtr = lookupForAdd(cx, seq); - if (addPtr) { - return addPtr.get()->asAtom(); - } - - // Compute the target encoding. - // NOTE: Length in code-points will be same, even if we deflate to Latin1. - bool wide = false; - InflatedChar16Sequence seqCopy = seq; - while (seqCopy.hasMore()) { - char16_t ch = seqCopy.next(); - if (ch > MAX_LATIN1_CHAR) { - wide = true; - break; - } - } - - // Otherwise, add new entry. - return wide ? internChar16Seq(cx, addPtr, seq, length) - : internChar16Seq(cx, addPtr, seq, length); -} - JS::Result ParserAtomsTable::internUtf8( JSContext* cx, const mozilla::Utf8Unit* utf8Ptr, uint32_t nbyte) { // Check for tiny strings which are abundant in minified code. @@ -770,157 +702,6 @@ bool WellKnownParserAtoms::init(JSContext* cx) { } /* namespace frontend */ } /* namespace js */ -// XDR code. -namespace js { - -template -static XDRResult XDRParserAtomIndex(XDRState* xdr, uint32_t* index) { - return xdr->codeUint32(index); -} - -template -XDRResult XDRParserAtomData(XDRState* xdr, const ParserAtom** atomp) { - static_assert(JSString::MAX_LENGTH <= INT32_MAX, - "String length must fit in 31 bits"); - - bool latin1 = false; - uint32_t length = 0; - uint32_t lengthAndEncoding = 0; - - /* Encode/decode the length and string-data encoding (Latin1 or TwoByte). */ - - if (mode == XDR_ENCODE) { - latin1 = (*atomp)->hasLatin1Chars(); - length = (*atomp)->length(); - lengthAndEncoding = (length << 1) | uint32_t(latin1); - } - - MOZ_TRY(xdr->codeUint32(&lengthAndEncoding)); - - if (mode == XDR_DECODE) { - length = lengthAndEncoding >> 1; - latin1 = !!(lengthAndEncoding & 0x1); - } - - /* Encode the character data. */ - if (mode == XDR_ENCODE) { - return latin1 - ? xdr->codeChars( - const_cast((*atomp)->latin1Chars()), - length) - : xdr->codeChars(const_cast((*atomp)->twoByteChars()), - length); - } - - /* Decode the character data. */ - MOZ_ASSERT(mode == XDR_DECODE); - JSContext* cx = xdr->cx(); - JS::Result mbAtom(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(ptr); - } - mbAtom = xdr->frontendAtoms().internLatin1(cx, chars, length); - } else { - const uint8_t* twoByteCharsLE = nullptr; - if (length) { - MOZ_TRY(xdr->peekData(&twoByteCharsLE, length * sizeof(char16_t))); - } - LittleEndianChars leTwoByte(twoByteCharsLE); - mbAtom = xdr->frontendAtoms().internChar16LE(cx, leTwoByte, length); - } - - const ParserAtom* atom = mbAtom.unwrapOr(nullptr); - if (!atom) { - return xdr->fail(JS::TranscodeResult_Throw); - } - *atomp = atom; - return Ok(); -} - -template -XDRResult XDRParserAtom(XDRState* xdr, const ParserAtom** atomp) { - // If dedup tables aren't enabled for this XDR encoding, encode/decode - // the parser atoms inline. - if (!xdr->hasAtomMap() && !xdr->hasAtomTable()) { - return XDRParserAtomData(xdr, atomp); - } - - if (mode == XDR_ENCODE) { - MOZ_ASSERT(xdr->hasAtomMap()); - - // Atom contents are encoded in a separate buffer, which is joined to the - // final result in XDRIncrementalEncoder::linearize. References to atoms - // are encoded as indices into the atom stream. - uint32_t atomIndex; - XDRParserAtomMap::AddPtr p = xdr->parserAtomMap().lookupForAdd(*atomp); - if (p) { - atomIndex = p->value(); - } else { - xdr->switchToAtomBuf(); - MOZ_TRY(XDRParserAtomData(xdr, atomp)); - xdr->switchToMainBuf(); - - atomIndex = xdr->natoms(); - xdr->natoms() += 1; - if (!xdr->parserAtomMap().add(p, *atomp, atomIndex)) { - return xdr->fail(JS::TranscodeResult_Throw); - } - } - MOZ_TRY(XDRParserAtomIndex(xdr, &atomIndex)); - return Ok(); - } - - MOZ_ASSERT(mode == XDR_DECODE && xdr->hasAtomTable()); - - uint32_t atomIndex; - MOZ_TRY(XDRParserAtomIndex(xdr, &atomIndex)); - if (atomIndex >= xdr->parserAtomTable().length()) { - return xdr->fail(JS::TranscodeResult_Failure_BadDecode); - } - const ParserAtom* atom = xdr->parserAtomTable()[atomIndex]; - - *atomp = atom; - return Ok(); -} - -template XDRResult XDRParserAtom(XDRState* xdr, - const ParserAtom** atomp); - -template XDRResult XDRParserAtom(XDRState* xdr, - const ParserAtom** atomp); - -template -XDRResult XDRParserAtomOrNull(XDRState* xdr, const ParserAtom** atomp) { - uint8_t isNull = false; - if (mode == XDR_ENCODE) { - if (!*atomp) { - isNull = true; - } - } - - MOZ_TRY(xdr->codeUint8(&isNull)); - - if (!isNull) { - MOZ_TRY(XDRParserAtom(xdr, atomp)); - } else if (mode == XDR_DECODE) { - *atomp = nullptr; - } - - return Ok(); -} - -template XDRResult XDRParserAtomOrNull(XDRState* xdr, - const ParserAtom** atomp); - -template XDRResult XDRParserAtomOrNull(XDRState* xdr, - const ParserAtom** atomp); - -} /* namespace js */ - bool JSRuntime::initializeParserAtoms(JSContext* cx) { MOZ_ASSERT(!commonParserNames); diff --git a/js/src/frontend/ParserAtom.h b/js/src/frontend/ParserAtom.h index 14c8199e7483..5c640dcac1be 100644 --- a/js/src/frontend/ParserAtom.h +++ b/js/src/frontend/ParserAtom.h @@ -437,30 +437,23 @@ class WellKnownParserAtoms { const SpecificParserAtomLookup& lookup) const; // Fast-path tiny strings since they are abundant in minified code. - template - const ParserAtom* lookupTiny(CharsT chars, size_t length) const { - static_assert(std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v, - "This assert mostly explicitly documents the calling types, " - "and forces that to be updated if new types show up."); + template + const ParserAtom* lookupTiny(const CharT* charPtr, uint32_t length) const { switch (length) { case 0: return empty; case 1: { - if (char16_t(chars[0]) < ASCII_STATIC_LIMIT) { - return getLength1String(chars[0]); + if (char16_t(charPtr[0]) < ASCII_STATIC_LIMIT) { + return getLength1String(charPtr[0]); } break; } case 2: - if (StaticStrings::fitsInSmallChar(chars[0]) && - StaticStrings::fitsInSmallChar(chars[1])) { - return getLength2String(chars[0], chars[1]); + if (StaticStrings::fitsInSmallChar(charPtr[0]) && + StaticStrings::fitsInSmallChar(charPtr[1])) { + return getLength2String(charPtr[0], charPtr[1]); } break; } @@ -535,8 +528,6 @@ class ParserAtomsTable { uint32_t length); public: - bool empty() const { return entrySet_.empty(); } - JS::Result internAscii(JSContext* cx, const char* asciiPtr, uint32_t length); @@ -551,11 +542,6 @@ class ParserAtomsTable { const char16_t* char16Ptr, uint32_t length); - // This only exists for XDR support. - JS::Result internChar16LE(JSContext* cx, - LittleEndianChars twoByteLE, - uint32_t length); - JS::Result internJSAtom( JSContext* cx, CompilationInfo& compilationInfo, JSAtom* atom); diff --git a/js/src/frontend/Stencil.cpp b/js/src/frontend/Stencil.cpp index b07913a0eacd..bbee7330caa6 100644 --- a/js/src/frontend/Stencil.cpp +++ b/js/src/frontend/Stencil.cpp @@ -12,12 +12,11 @@ #include "frontend/BytecodeSection.h" // EmitScriptThingsVector #include "frontend/CompilationInfo.h" // CompilationInfo #include "frontend/SharedContext.h" -#include "gc/AllocKind.h" // gc::AllocKind -#include "js/CallArgs.h" // JSNative -#include "js/RootingAPI.h" // Rooted -#include "js/Transcoding.h" // JS::TranscodeBuffer -#include "js/Value.h" // ObjectValue -#include "js/WasmModule.h" // JS::WasmModule +#include "gc/AllocKind.h" // gc::AllocKind +#include "js/CallArgs.h" // JSNative +#include "js/RootingAPI.h" // Rooted +#include "js/Value.h" // ObjectValue +#include "js/WasmModule.h" // JS::WasmModule #include "vm/EnvironmentObject.h" #include "vm/GeneratorAndAsyncKind.h" // GeneratorKind, FunctionAsyncKind #include "vm/JSContext.h" // JSContext @@ -30,7 +29,6 @@ #include "vm/Scope.h" // Scope, ScopeKindString #include "vm/StencilEnums.h" // ImmutableScriptFlagsEnum #include "vm/StringType.h" // JSAtom, js::CopyChars -#include "vm/Xdr.h" // XDRMode, XDRResult, XDREncoder #include "wasm/AsmJS.h" // InstantiateAsmJS #include "wasm/WasmModule.h" // wasm::Module @@ -602,63 +600,6 @@ bool CompilationInfo::instantiateStencils(JSContext* cx, return true; } -bool CompilationInfo::serializeStencils(JSContext* cx, JS::TranscodeBuffer& buf, - bool* succeededOut) { - if (succeededOut) { - *succeededOut = false; - } - XDRIncrementalStencilEncoder encoder(cx, *this); - - XDRResult res = encoder.codeStencil(stencil); - if (res.isErr()) { - if (res.unwrapErr() & JS::TranscodeResult_Failure) { - buf.clear(); - return true; - } - MOZ_ASSERT(res.unwrapErr() == JS::TranscodeResult_Throw); - - return false; - } - - // Lineareize the endcoder, return empty buffer on failure. - res = encoder.linearize(buf); - if (res.isErr()) { - buf.clear(); - return false; - } - - if (succeededOut) { - *succeededOut = true; - } - return true; -} - -bool CompilationInfo::deserializeStencils(JSContext* cx, - const JS::TranscodeRange& range, - bool* succeededOut) { - if (succeededOut) { - *succeededOut = false; - } - MOZ_ASSERT(stencil.parserAtoms.empty()); - XDRStencilDecoder decoder(cx, &input.options, range, *this, - stencil.parserAtoms); - - XDRResult res = decoder.codeStencil(stencil); - if (res.isErr()) { - if (res.unwrapErr() & JS::TranscodeResult_Failure) { - return true; - } - MOZ_ASSERT(res.unwrapErr() == JS::TranscodeResult_Throw); - - return false; - } - - if (succeededOut) { - *succeededOut = true; - } - return true; -} - #if defined(DEBUG) || defined(JS_JITSPEW) void RegExpStencil::dump() { diff --git a/js/src/frontend/Stencil.h b/js/src/frontend/Stencil.h index 7c3543d1e4ee..ee07f65af3ed 100644 --- a/js/src/frontend/Stencil.h +++ b/js/src/frontend/Stencil.h @@ -46,7 +46,6 @@ struct CompilationGCOutput; class ScriptStencil; class RegExpStencil; class BigIntStencil; -class StencilXDR; using BaseParserScopeData = AbstractBaseScopeData; @@ -85,8 +84,6 @@ FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind, // This owns a set of characters, previously syntax checked as a RegExp. Used // to avoid allocating the RegExp on the GC heap during parsing. class RegExpStencil { - friend class StencilXDR; - UniqueTwoByteChars buf_; size_t length_ = 0; JS::RegExpFlags flags_; @@ -117,8 +114,6 @@ class RegExpStencil { // ParseBigIntLiteral. Used to avoid allocating the BigInt on the // GC heap during parsing. class BigIntStencil { - friend class StencilXDR; - UniqueTwoByteChars buf_; size_t length_ = 0; @@ -156,17 +151,15 @@ class BigIntStencil { }; class ScopeStencil { - friend class StencilXDR; - // The enclosing scope. If Nothing, then the enclosing scope of the // compilation applies. mozilla::Maybe enclosing_; // The kind determines data_. - ScopeKind kind_{UINT8_MAX}; + ScopeKind kind_; // First frame slot to use, or LOCALNO_LIMIT if none are allowed. - uint32_t firstFrameSlot_ = UINT32_MAX; + uint32_t firstFrameSlot_; // If Some, then an environment Shape must be created. The shape itself may // have no slots if the environment may be extensible later. @@ -176,7 +169,7 @@ class ScopeStencil { mozilla::Maybe functionIndex_; // True if this is a FunctionScope for an arrow function. - bool isArrow_ = false; + bool isArrow_; // The list of binding and scope-specific data. Note that the back pointers to // the owning JSFunction / ModuleObject are not set until Stencils are @@ -184,9 +177,6 @@ class ScopeStencil { js::UniquePtr data_; public: - // For XDR only. - ScopeStencil() = default; - ScopeStencil(ScopeKind kind, mozilla::Maybe enclosing, uint32_t firstFrameSlot, mozilla::Maybe numEnvironmentSlots, @@ -201,8 +191,6 @@ class ScopeStencil { isArrow_(isArrow), data_(data) {} - js::UniquePtr& data() { return data_; } - static bool createForFunctionScope(JSContext* cx, CompilationStencil& stencil, ParserFunctionScopeData* dataArg, bool hasParameterExprs, @@ -347,9 +335,6 @@ class StencilModuleEntry { : lineno(lineno), column(column) {} public: - // For XDR only. - StencilModuleEntry() = default; - static StencilModuleEntry moduleRequest(const ParserAtom* specifier, uint32_t lineno, uint32_t column) { MOZ_ASSERT(specifier); diff --git a/js/src/frontend/StencilXdr.cpp b/js/src/frontend/StencilXdr.cpp deleted file mode 100644 index 4d3d09c81b62..000000000000 --- a/js/src/frontend/StencilXdr.cpp +++ /dev/null @@ -1,920 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "frontend/StencilXdr.h" // StencilXDR - -using namespace js; -using namespace js::frontend; - -struct ScriptThingVariantIndexMatcher { - template - uint32_t operator()(TypedIndex& index) { - return index; - } - - template - uint32_t operator()(T&) { - return UINT32_MAX; - } -}; - -template -static XDRResult XDRScriptThingVariant(XDRState* xdr, - ScriptThingVariant& thing) { - enum class ScriptThingKind { - ScriptAtom, // JSAtom* - NullScriptThing, // nothing. - BigIntIndex, // Index. - ObjLiteralIndex, // Index. - RegExpIndex, // Index. - ScopeIndex, // Index. - FunctionIndex, // Index. - EmptyGlobalScopeType, // Nothing - } kind; - - uint32_t index = UINT32_MAX; - - struct KindMatcher { - ScriptThingKind operator()(ScriptAtom& atom) { - return ScriptThingKind::ScriptAtom; - } - ScriptThingKind operator()(NullScriptThing&) { - return ScriptThingKind::NullScriptThing; - } - ScriptThingKind operator()(BigIntIndex& index) { - return ScriptThingKind::BigIntIndex; - } - ScriptThingKind operator()(ObjLiteralIndex& index) { - return ScriptThingKind::ObjLiteralIndex; - } - ScriptThingKind operator()(RegExpIndex& index) { - return ScriptThingKind::RegExpIndex; - } - ScriptThingKind operator()(ScopeIndex& index) { - return ScriptThingKind::ScopeIndex; - } - ScriptThingKind operator()(FunctionIndex& index) { - return ScriptThingKind::FunctionIndex; - } - ScriptThingKind operator()(EmptyGlobalScopeType&) { - return ScriptThingKind::EmptyGlobalScopeType; - } - }; - - if (mode == XDR_ENCODE) { - kind = thing.match(KindMatcher()); - index = thing.match(ScriptThingVariantIndexMatcher()); - } - - MOZ_TRY(xdr->codeEnum32(&kind)); - - const ParserAtom* atom = nullptr; - if (kind == ScriptThingKind::ScriptAtom) { - MOZ_ASSERT(index == UINT32_MAX); - if (mode == XDR_ENCODE) { - atom = thing.as(); - } - MOZ_TRY(XDRParserAtom(xdr, &atom)); - } else if (kind == ScriptThingKind::BigIntIndex || - kind == ScriptThingKind::ObjLiteralIndex || - kind == ScriptThingKind::RegExpIndex || - kind == ScriptThingKind::ScopeIndex || - kind == ScriptThingKind::FunctionIndex) { - MOZ_TRY(xdr->codeUint32(&index)); - } else { - MOZ_ASSERT(kind == ScriptThingKind::NullScriptThing || - kind == ScriptThingKind::EmptyGlobalScopeType); - } - - if (mode == XDR_DECODE) { - switch (kind) { - case ScriptThingKind::ScriptAtom: - // `atom` is initialized above if `kind` == ScriptAtom - MOZ_ASSERT(atom != nullptr); - thing.emplace(atom); - break; - case ScriptThingKind::NullScriptThing: - thing.emplace(); - break; - case ScriptThingKind::EmptyGlobalScopeType: - thing.emplace(); - break; - case ScriptThingKind::BigIntIndex: - thing.emplace(index); - break; - case ScriptThingKind::ObjLiteralIndex: - thing.emplace(index); - break; - case ScriptThingKind::RegExpIndex: - thing.emplace(index); - break; - case ScriptThingKind::ScopeIndex: - thing.emplace(index); - break; - case ScriptThingKind::FunctionIndex: - thing.emplace(index); - break; - } - } - - return Ok(); -} - -template -static XDRResult XDRScriptStencil(XDRState* xdr, ScriptStencil& stencil) { - enum class XdrFlags : uint8_t { - HasMemberInitializers = 0, - HasScopeIndex, - IsStandaloneFunction, - WasFunctionEmitted, - IsSingletonFunction, - HasImmutableScriptData - }; - - uint8_t xdrFlags = 0; - uint32_t immutableFlags; - uint32_t numMemberInitializers; - uint32_t numGcThings; - uint16_t functionFlags; - uint32_t scopeIndex; - - if (mode == XDR_ENCODE) { - immutableFlags = stencil.immutableFlags; - - if (stencil.memberInitializers.isSome()) { - xdrFlags |= 1 << uint8_t(XdrFlags::HasMemberInitializers); - } - numMemberInitializers = - stencil.memberInitializers - .map([](auto i) { return i.numMemberInitializers; }) - .valueOr(0); - - numGcThings = stencil.gcThings.length(); - - if (stencil.immutableScriptData) { - xdrFlags |= 1 << uint8_t(XdrFlags::HasImmutableScriptData); - } - - functionFlags = stencil.functionFlags.toRaw(); - - if (stencil.lazyFunctionEnclosingScopeIndex_.isSome()) { - xdrFlags |= 1 << uint8_t(XdrFlags::HasScopeIndex); - } - scopeIndex = stencil.lazyFunctionEnclosingScopeIndex_.valueOr(ScopeIndex()); - - if (stencil.isStandaloneFunction) { - xdrFlags |= 1 << uint8_t(XdrFlags::IsStandaloneFunction); - } - if (stencil.wasFunctionEmitted) { - xdrFlags |= 1 << uint8_t(XdrFlags::WasFunctionEmitted); - } - if (stencil.isSingletonFunction) { - xdrFlags |= 1 << uint8_t(XdrFlags::IsSingletonFunction); - } - } - - MOZ_TRY(xdr->codeUint8(&xdrFlags)); - MOZ_TRY(xdr->codeUint32(&immutableFlags)); - MOZ_TRY(xdr->codeUint32(&numMemberInitializers)); - MOZ_TRY(xdr->codeUint32(&numGcThings)); - MOZ_TRY(xdr->codeUint16(&functionFlags)); - MOZ_TRY(xdr->codeUint32(&scopeIndex)); - MOZ_TRY(xdr->codeUint16(&stencil.nargs)); - - if (mode == XDR_DECODE) { - stencil.immutableFlags = immutableFlags; - - if (xdrFlags & (1 << uint8_t(XdrFlags::HasMemberInitializers))) { - stencil.memberInitializers.emplace(numMemberInitializers); - } - - if (!stencil.gcThings.appendN(mozilla::AsVariant(NullScriptThing()), - numGcThings)) { - ReportOutOfMemory(xdr->cx()); - return xdr->fail(JS::TranscodeResult_Throw); - } - - stencil.functionFlags = FunctionFlags(functionFlags); - - MOZ_ASSERT_IF((xdrFlags & (1 << uint8_t(XdrFlags::HasScopeIndex))) == 0, - scopeIndex == 0); - if (xdrFlags & (1 << uint8_t(XdrFlags::HasScopeIndex))) { - stencil.lazyFunctionEnclosingScopeIndex_.emplace(scopeIndex); - } - - if (xdrFlags & (1 << uint8_t(XdrFlags::IsStandaloneFunction))) { - stencil.isStandaloneFunction = true; - } - if (xdrFlags & (1 << uint8_t(XdrFlags::WasFunctionEmitted))) { - stencil.wasFunctionEmitted = true; - } - if (xdrFlags & (1 << uint8_t(XdrFlags::IsSingletonFunction))) { - stencil.isSingletonFunction = true; - } - } - - MOZ_TRY(XDRSourceExtent(xdr, &stencil.extent)); - - if (xdrFlags & (1 << uint8_t(XdrFlags::HasImmutableScriptData))) { - MOZ_TRY(XDRImmutableScriptData(xdr, stencil.immutableScriptData)); - } - - for (ScriptThingVariant& thing : stencil.gcThings) { - MOZ_TRY(XDRScriptThingVariant(xdr, thing)); - } - - MOZ_TRY(XDRParserAtomOrNull(xdr, &stencil.functionAtom)); - - return Ok(); -}; - -template -static XDRResult XDRParserBindingName(XDRState* xdr, - ParserBindingName& bnamep) { - // We'll be encoding the binding-name flags in a byte. - uint8_t flags = 0; - const ParserAtom* atom = nullptr; - - if (mode == XDR_ENCODE) { - flags = bnamep.flagsForXDR(); - atom = bnamep.name(); - } - - // Handle the binding name flags. - MOZ_TRY(xdr->codeUint8(&flags)); - - // Handle the atom itself, which may be null. - MOZ_TRY(XDRParserAtomOrNull(xdr, &atom)); - - if (mode == XDR_ENCODE) { - return Ok(); - } - - MOZ_ASSERT(mode == XDR_DECODE); - bnamep = ParserBindingName::fromXDR(atom, flags); - return Ok(); -} - -template -static XDRResult XDRParserTrailingNames(XDRState* xdr, ScopeDataT& data, - uint32_t length) { - // Handle each atom in turn. - for (uint32_t i = 0; i < length; i++) { - MOZ_TRY(XDRParserBindingName(xdr, data.trailingNames[i])); - } - - return Ok(); -} - -template -static UniquePtr NewEmptyScopeData(JSContext* cx, - uint32_t length, - InitF init) { - size_t dataSize = SizeOfScopeData>(length); - uint8_t* bytes = cx->pod_malloc(dataSize); - if (!bytes) { - return nullptr; - } - auto* data = new (bytes) ParserScopeData(length); - init(data); - return UniquePtr(data); -} - -template -static XDRResult XDRParserFunctionScopeData( - XDRState* xdr, UniquePtr& ownedData) { - ParserFunctionScopeData* data = - static_cast(ownedData.get()); - - uint32_t nextFrameSlot = 0; - uint8_t hasParameterExprs = 0; - uint16_t nonPositionalFormalStart = 0; - uint16_t varStart = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - nextFrameSlot = data->nextFrameSlot; - hasParameterExprs = data->hasParameterExprs ? 1 : 0; - nonPositionalFormalStart = data->nonPositionalFormalStart; - varStart = data->varStart; - length = data->length; - } - - MOZ_TRY(xdr->codeUint32(&nextFrameSlot)); - MOZ_TRY(xdr->codeUint8(&hasParameterExprs)); - MOZ_TRY(xdr->codeUint16(&nonPositionalFormalStart)); - MOZ_TRY(xdr->codeUint16(&varStart)); - MOZ_TRY(xdr->codeUint32(&length)); - - // Reconstruct the scope-data object for decode. - if (mode == XDR_DECODE) { - MOZ_ASSERT(!ownedData); - ownedData = - NewEmptyScopeData(xdr->cx(), length, [&](auto data) { - data->nextFrameSlot = nextFrameSlot; - MOZ_ASSERT(hasParameterExprs <= 1); - data->hasParameterExprs = hasParameterExprs; - data->nonPositionalFormalStart = nonPositionalFormalStart; - data->varStart = varStart; - data->length = length; - }); - if (!ownedData) { - return xdr->fail(JS::TranscodeResult_Throw); - } - data = static_cast(ownedData.get()); - } - - // Decode each name in TrailingNames. - MOZ_TRY(XDRParserTrailingNames(xdr, *data, length)); - - return Ok(); -} - -template -static XDRResult XDRParserVarScopeData( - XDRState* xdr, UniquePtr& ownedData) { - ParserVarScopeData* data = static_cast(ownedData.get()); - - uint32_t nextFrameSlot = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - nextFrameSlot = data->nextFrameSlot; - length = data->length; - } - - MOZ_TRY(xdr->codeUint32(&nextFrameSlot)); - MOZ_TRY(xdr->codeUint32(&length)); - - // Reconstruct the scope-data object for decode. - if (mode == XDR_DECODE) { - MOZ_ASSERT(!ownedData); - ownedData = NewEmptyScopeData(xdr->cx(), length, [&](auto data) { - data->nextFrameSlot = nextFrameSlot; - data->length = length; - }); - if (!ownedData) { - return xdr->fail(JS::TranscodeResult_Throw); - } - data = static_cast(ownedData.get()); - } - - // Decode each name in TrailingNames. - MOZ_TRY(XDRParserTrailingNames(xdr, *data, length)); - - return Ok(); -} - -template -static XDRResult XDRParserLexicalScopeData( - XDRState* xdr, UniquePtr& ownedData) { - ParserLexicalScopeData* data = - static_cast(ownedData.get()); - - uint32_t nextFrameSlot = 0; - uint32_t constStart = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - nextFrameSlot = data->nextFrameSlot; - constStart = data->constStart; - length = data->length; - } - - MOZ_TRY(xdr->codeUint32(&nextFrameSlot)); - MOZ_TRY(xdr->codeUint32(&constStart)); - MOZ_TRY(xdr->codeUint32(&length)); - - // Reconstruct the scope-data object for decode. - if (mode == XDR_DECODE) { - MOZ_ASSERT(!ownedData); - ownedData = - NewEmptyScopeData(xdr->cx(), length, [&](auto data) { - data->nextFrameSlot = nextFrameSlot; - data->constStart = constStart; - data->length = length; - }); - if (!ownedData) { - return xdr->fail(JS::TranscodeResult_Throw); - } - data = static_cast(ownedData.get()); - } - - // Decode each name in TrailingNames. - MOZ_TRY(XDRParserTrailingNames(xdr, *data, length)); - - return Ok(); -} - -template -static XDRResult XDRParserGlobalScopeData( - XDRState* xdr, UniquePtr& ownedData) { - ParserGlobalScopeData* data = - static_cast(ownedData.get()); - - uint32_t letStart = 0; - uint32_t constStart = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - letStart = data->letStart; - constStart = data->constStart; - length = data->length; - } - - MOZ_TRY(xdr->codeUint32(&letStart)); - MOZ_TRY(xdr->codeUint32(&constStart)); - MOZ_TRY(xdr->codeUint32(&length)); - - // Reconstruct the scope-data object for decode. - if (mode == XDR_DECODE) { - MOZ_ASSERT(!ownedData); - ownedData = - NewEmptyScopeData(xdr->cx(), length, [&](auto data) { - data->letStart = letStart; - data->constStart = constStart; - data->length = length; - }); - if (!ownedData) { - return xdr->fail(JS::TranscodeResult_Throw); - } - data = static_cast(ownedData.get()); - } - - // Decode each name in TrailingNames. - MOZ_TRY(XDRParserTrailingNames(xdr, *data, length)); - - return Ok(); -} - -template -static XDRResult XDRParserModuleScopeData( - XDRState* xdr, UniquePtr& ownedData) { - ParserModuleScopeData* data = - static_cast(ownedData.get()); - - uint32_t nextFrameSlot = 0; - uint32_t varStart = 0; - uint32_t letStart = 0; - uint32_t constStart = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - nextFrameSlot = data->nextFrameSlot; - varStart = data->varStart; - letStart = data->letStart; - constStart = data->constStart; - length = data->length; - } - - MOZ_TRY(xdr->codeUint32(&nextFrameSlot)); - MOZ_TRY(xdr->codeUint32(&varStart)); - MOZ_TRY(xdr->codeUint32(&letStart)); - MOZ_TRY(xdr->codeUint32(&constStart)); - MOZ_TRY(xdr->codeUint32(&length)); - - // Reconstruct the scope-data object for decode. - if (mode == XDR_DECODE) { - MOZ_ASSERT(!ownedData); - ownedData = - NewEmptyScopeData(xdr->cx(), length, [&](auto data) { - data->nextFrameSlot = nextFrameSlot; - data->varStart = varStart; - data->letStart = letStart; - data->constStart = constStart; - data->length = length; - }); - if (!ownedData) { - return xdr->fail(JS::TranscodeResult_Throw); - } - data = static_cast(ownedData.get()); - } - - // Decode each name in TrailingNames. - MOZ_TRY(XDRParserTrailingNames(xdr, *data, length)); - - return Ok(); -} - -template -static XDRResult XDRParserEvalScopeData( - XDRState* xdr, UniquePtr& ownedData) { - ParserEvalScopeData* data = - static_cast(ownedData.get()); - - uint32_t nextFrameSlot = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - nextFrameSlot = data->nextFrameSlot; - length = data->length; - } - - MOZ_TRY(xdr->codeUint32(&nextFrameSlot)); - MOZ_TRY(xdr->codeUint32(&length)); - - // Reconstruct the scope-data object for decode. - if (mode == XDR_DECODE) { - MOZ_ASSERT(!ownedData); - ownedData = NewEmptyScopeData(xdr->cx(), length, [&](auto data) { - data->nextFrameSlot = nextFrameSlot; - data->length = length; - }); - if (!ownedData) { - return xdr->fail(JS::TranscodeResult_Throw); - } - data = static_cast(ownedData.get()); - } - - // Decode each name in TrailingNames. - MOZ_TRY(XDRParserTrailingNames(xdr, *data, length)); - - return Ok(); -} - -template -static XDRResult XDRVector(XDRState* xdr, VecType& vec, - ConstructArgs&&... args) { - uint32_t length; - - if (mode == XDR_ENCODE) { - MOZ_ASSERT(vec.length() <= UINT32_MAX); - length = vec.length(); - } - - MOZ_TRY(xdr->codeUint32(&length)); - - if (mode == XDR_DECODE) { - MOZ_ASSERT(vec.empty()); - if (!vec.reserve(length)) { - js::ReportOutOfMemory(xdr->cx()); - return xdr->fail(JS::TranscodeResult_Throw); - } - for (uint64_t i = 0; i < length; ++i) { - vec.infallibleEmplaceBack(std::forward(args)...); - } - } - - return Ok(); -} - -template -static XDRResult XDRObjLiteralWriter(XDRState* xdr, - ObjLiteralWriter& writer) { - uint8_t flags = 0; - uint32_t length = 0; - - if (mode == XDR_ENCODE) { - flags = writer.getFlags().serialize(); - length = writer.getCode().size(); - } - - MOZ_TRY(xdr->codeUint8(&flags)); - MOZ_TRY(xdr->codeUint32(&length)); - - if (mode == XDR_ENCODE) { - MOZ_TRY(xdr->codeBytes((void*)writer.getCode().data(), length)); - return Ok(); - } - - MOZ_ASSERT(mode == XDR_DECODE); - ObjLiteralWriter::CodeVector codeVec; - if (!codeVec.appendN(0, length)) { - return xdr->fail(JS::TranscodeResult_Throw); - } - MOZ_TRY(xdr->codeBytes(codeVec.begin(), length)); - - writer.initializeForXDR(std::move(codeVec), flags); - - return Ok(); -} - -template -static XDRResult XDRStencilModuleEntryVector( - XDRState* xdr, StencilModuleMetadata::EntryVector& vec) { - uint64_t length; - - if (mode == XDR_ENCODE) { - length = vec.length(); - } - - MOZ_TRY(xdr->codeUint64(&length)); - - if (mode == XDR_DECODE) { - MOZ_ASSERT(vec.empty()); - if (!vec.resize(length)) { - return xdr->fail(JS::TranscodeResult_Throw); - } - } - - for (StencilModuleEntry& entry : vec) { - MOZ_TRY(xdr->codeUint32(&entry.lineno)); - MOZ_TRY(xdr->codeUint32(&entry.column)); - - MOZ_TRY(XDRParserAtomOrNull(xdr, &entry.specifier)); - MOZ_TRY(XDRParserAtomOrNull(xdr, &entry.localName)); - MOZ_TRY(XDRParserAtomOrNull(xdr, &entry.importName)); - MOZ_TRY(XDRParserAtomOrNull(xdr, &entry.exportName)); - } - - return Ok(); -} - -template -static XDRResult XDRStencilModuleMetadata(XDRState* xdr, - StencilModuleMetadata& stencil) { - MOZ_TRY(XDRStencilModuleEntryVector(xdr, stencil.requestedModules)); - MOZ_TRY(XDRStencilModuleEntryVector(xdr, stencil.importEntries)); - MOZ_TRY(XDRStencilModuleEntryVector(xdr, stencil.localExportEntries)); - MOZ_TRY(XDRStencilModuleEntryVector(xdr, stencil.indirectExportEntries)); - MOZ_TRY(XDRStencilModuleEntryVector(xdr, stencil.starExportEntries)); - - { - uint64_t length; - - if (mode == XDR_ENCODE) { - length = stencil.functionDecls.length(); - } - - MOZ_TRY(xdr->codeUint64(&length)); - - if (mode == XDR_DECODE) { - MOZ_ASSERT(stencil.functionDecls.empty()); - if (!stencil.functionDecls.resize(length)) { - return xdr->fail(JS::TranscodeResult_Throw); - } - } - - for (GCThingIndex& entry : stencil.functionDecls) { - MOZ_TRY(xdr->codeUint32(&entry.index)); - } - } - - return Ok(); -} - -template -/* static */ XDRResult StencilXDR::Scope(XDRState* xdr, - ScopeStencil& stencil) { - enum class XdrFlags { - HasEnclosing, - HasEnvironment, - IsArrow, - }; - - uint8_t xdrFlags = 0; - uint8_t kind; - - if (mode == XDR_ENCODE) { - kind = static_cast(stencil.kind_); - if (stencil.enclosing_.isSome()) { - xdrFlags |= 1 << uint8_t(XdrFlags::HasEnclosing); - } - if (stencil.numEnvironmentSlots_.isSome()) { - xdrFlags |= 1 << uint8_t(XdrFlags::HasEnvironment); - } - if (stencil.isArrow_) { - xdrFlags |= 1 << uint8_t(XdrFlags::IsArrow); - } - } - - MOZ_TRY(xdr->codeUint8(&xdrFlags)); - MOZ_TRY(xdr->codeUint8(&kind)); - MOZ_TRY(xdr->codeUint32(&stencil.firstFrameSlot_)); - - if (mode == XDR_DECODE) { - stencil.kind_ = static_cast(kind); - } - - if (xdrFlags & (1 << uint8_t(XdrFlags::HasEnclosing))) { - if (mode == XDR_DECODE) { - stencil.enclosing_ = mozilla::Some(ScopeIndex()); - } - MOZ_ASSERT(stencil.enclosing_.isSome()); - MOZ_TRY(xdr->codeUint32(&stencil.enclosing_->index)); - } - - if (xdrFlags & (1 << uint8_t(XdrFlags::HasEnvironment))) { - if (mode == XDR_DECODE) { - stencil.numEnvironmentSlots_ = mozilla::Some(0); - } - MOZ_ASSERT(stencil.numEnvironmentSlots_.isSome()); - MOZ_TRY(xdr->codeUint32(&stencil.numEnvironmentSlots_.ref())); - } - - if (xdrFlags & (1 << uint8_t(XdrFlags::IsArrow))) { - if (mode == XDR_DECODE) { - stencil.isArrow_ = true; - } - } - - if (stencil.kind_ == ScopeKind::Function) { - if (mode == XDR_DECODE) { - stencil.functionIndex_ = mozilla::Some(FunctionIndex()); - } - MOZ_ASSERT(stencil.functionIndex_.isSome()); - MOZ_TRY(xdr->codeUint32(&stencil.functionIndex_->index)); - } - - // In both decoding and encoding, stencil.kind_ is now known, and - // can be assumed. This allows the encoding to write out the bytes - // for the specialized scope-data type without needing to encode - // a distinguishing prefix. - switch (stencil.kind_) { - // FunctionScope - case ScopeKind::Function: { - MOZ_TRY(XDRParserFunctionScopeData(xdr, stencil.data_)); - break; - } - - // VarScope - case ScopeKind::FunctionBodyVar: { - MOZ_TRY(XDRParserVarScopeData(xdr, stencil.data_)); - break; - } - - // LexicalScope - case ScopeKind::Lexical: - case ScopeKind::SimpleCatch: - case ScopeKind::Catch: - case ScopeKind::NamedLambda: - case ScopeKind::StrictNamedLambda: - case ScopeKind::FunctionLexical: - case ScopeKind::ClassBody: { - MOZ_TRY(XDRParserLexicalScopeData(xdr, stencil.data_)); - break; - } - - // WithScope - case ScopeKind::With: { - // With scopes carry no scope data. - break; - } - - // EvalScope - case ScopeKind::Eval: - case ScopeKind::StrictEval: { - MOZ_TRY(XDRParserEvalScopeData(xdr, stencil.data_)); - break; - } - - // GlobalScope - case ScopeKind::Global: - case ScopeKind::NonSyntactic: { - MOZ_TRY(XDRParserGlobalScopeData(xdr, stencil.data_)); - break; - } - - // ModuleScope - case ScopeKind::Module: { - MOZ_TRY(XDRParserModuleScopeData(xdr, stencil.data_)); - break; - } - - // WasmInstanceScope & WasmFunctionScope should not appear in stencils. - case ScopeKind::WasmInstance: - case ScopeKind::WasmFunction: - default: - MOZ_ASSERT_UNREACHABLE("XDR unrecognized ScopeKind."); - } - - return Ok(); -} - -template -/* static */ XDRResult StencilXDR::ObjLiteral(XDRState* xdr, - ObjLiteralStencil& stencil) { - MOZ_TRY(XDRObjLiteralWriter(xdr, stencil.writer_)); - - MOZ_TRY(XDRVector(xdr, stencil.atoms_, nullptr)); - for (const ParserAtom*& entry : stencil.atoms_) { - MOZ_TRY(XDRParserAtom(xdr, &entry)); - } - - return Ok(); -} - -template -/* static */ XDRResult StencilXDR::BigInt(XDRState* xdr, - BigIntStencil& stencil) { - uint64_t length; - - if (mode == XDR_ENCODE) { - length = stencil.length_; - } - - MOZ_TRY(xdr->codeUint64(&length)); - - XDRTranscodeString chars; - - if (mode == XDR_DECODE) { - stencil.buf_ = xdr->cx()->template make_pod_array(length); - if (!stencil.buf_) { - return xdr->fail(JS::TranscodeResult_Throw); - } - stencil.length_ = length; - } - - return xdr->codeChars(stencil.buf_.get(), stencil.length_); -} - -template -/* static */ XDRResult StencilXDR::RegExp(XDRState* xdr, - RegExpStencil& stencil) { - uint64_t length; - uint8_t flags; - - if (mode == XDR_ENCODE) { - length = stencil.length_; - flags = stencil.flags_.value(); - } - - MOZ_TRY(xdr->codeUint64(&length)); - MOZ_TRY(xdr->codeUint8(&flags)); - - XDRTranscodeString chars; - - if (mode == XDR_DECODE) { - stencil.buf_ = xdr->cx()->template make_pod_array(length); - if (!stencil.buf_) { - return xdr->fail(JS::TranscodeResult_Throw); - } - stencil.length_ = length; - stencil.flags_ = JS::RegExpFlags(flags); - } - - return xdr->codeChars(stencil.buf_.get(), stencil.length_); -} - -namespace js { - -template -XDRResult XDRCompilationStencil(XDRState* xdr, - CompilationStencil& stencil) { - if (!stencil.asmJS.empty()) { - return xdr->fail(JS::TranscodeResult_Failure_AsmJSNotSupported); - } - - // XDR the ScriptSource - CompilationInfo& compilationInfo = xdr->stencilCompilationInfo(); - - // Copy the options out for passing into `ScriptSource::XDR`. - mozilla::Maybe opts; - opts.emplace(xdr->cx(), compilationInfo.input.options); - - Rooted holder(xdr->cx()); - if (mode == XDR_ENCODE) { - holder.get().reset(compilationInfo.input.source_.get()); - } - MOZ_TRY(ScriptSource::XDR(xdr, opts, &holder)); - - if (mode == XDR_DECODE) { - compilationInfo.input.source_.reset(holder.get().get()); - } - - // All of the vector-indexed data elements referenced by the - // main script tree must be materialized first. - - MOZ_TRY(XDRVector(xdr, stencil.scopeData)); - for (auto& entry : stencil.scopeData) { - MOZ_TRY(StencilXDR::Scope(xdr, entry)); - } - - MOZ_TRY(XDRVector(xdr, stencil.regExpData)); - for (auto& entry : stencil.regExpData) { - MOZ_TRY(StencilXDR::RegExp(xdr, entry)); - } - - MOZ_TRY(XDRVector(xdr, stencil.bigIntData)); - for (auto& entry : stencil.bigIntData) { - MOZ_TRY(StencilXDR::BigInt(xdr, entry)); - } - - MOZ_TRY(XDRVector(xdr, stencil.objLiteralData)); - for (auto& entry : stencil.objLiteralData) { - MOZ_TRY(StencilXDR::ObjLiteral(xdr, entry)); - } - - // Now serialize the vector of ScriptStencils. - - MOZ_TRY(XDRVector(xdr, stencil.scriptData)); - for (auto& entry : stencil.scriptData) { - MOZ_TRY(XDRScriptStencil(xdr, entry)); - } - - if (stencil.scriptData[CompilationInfo::TopLevelIndex].isModule()) { - MOZ_TRY(XDRStencilModuleMetadata(xdr, stencil.moduleMetadata)); - } - - return Ok(); -} -template XDRResult XDRCompilationStencil(XDRState* xdr, - CompilationStencil& stencil); - -template XDRResult XDRCompilationStencil(XDRState* xdr, - CompilationStencil& stencil); - -} // namespace js diff --git a/js/src/frontend/StencilXdr.h b/js/src/frontend/StencilXdr.h deleted file mode 100644 index 5156c115912b..000000000000 --- a/js/src/frontend/StencilXdr.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef frontend_StencilXdr_h -#define frontend_StencilXdr_h - -#include "frontend/CompilationInfo.h" // CompilationInfo -#include "frontend/ObjLiteral.h" // ObjLiteralStencil -#include "frontend/Stencil.h" // Stencil -#include "vm/Scope.h" // Scope, ScopeKindString -#include "vm/Xdr.h" // XDRMode, XDRResult, XDREncoder - -namespace js { -namespace frontend { - -// This is just a namespace class that can be used in friend declarations, -// so that the statically declared XDR methods within have access to the -// relevant struct internals. -class StencilXDR { - public: - template - static XDRResult Scope(XDRState* xdr, ScopeStencil& stencil); - - template - static XDRResult ObjLiteral(XDRState* xdr, ObjLiteralStencil& stencil); - - template - static XDRResult BigInt(XDRState* xdr, BigIntStencil& stencil); - - template - static XDRResult RegExp(XDRState* xdr, RegExpStencil& stencil); -}; - -} /* namespace frontend */ -} /* namespace js */ - -#endif /* frontend_StencilXdr_h */ diff --git a/js/src/frontend/moz.build b/js/src/frontend/moz.build index 8cd30b3b4971..acf4ca867c93 100644 --- a/js/src/frontend/moz.build +++ b/js/src/frontend/moz.build @@ -58,7 +58,6 @@ UNIFIED_SOURCES += [ 'SharedContext.cpp', 'SourceNotes.cpp', 'Stencil.cpp', - 'StencilXdr.cpp', 'SwitchEmitter.cpp', 'TDZCheckCache.cpp', 'TokenStream.cpp', diff --git a/js/src/jsapi-tests/testParserAtom.cpp b/js/src/jsapi-tests/testParserAtom.cpp index a3828da1d5fc..937e5e2a527c 100644 --- a/js/src/jsapi-tests/testParserAtom.cpp +++ b/js/src/jsapi-tests/testParserAtom.cpp @@ -16,22 +16,20 @@ BEGIN_TEST(testParserAtom_empty) { ParserAtomsTable atomTable(cx->runtime()); + constexpr size_t len = 0; + const char ascii[] = {}; const JS::Latin1Char latin1[] = {}; const mozilla::Utf8Unit utf8[] = {}; 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.internChar16LE(cx, leTwoByte, 0).unwrap() == ref); + CHECK(atomTable.internAscii(cx, ascii, len).unwrap() == ref); + CHECK(atomTable.internLatin1(cx, latin1, len).unwrap() == ref); + CHECK(atomTable.internUtf8(cx, utf8, len).unwrap() == ref); + CHECK(atomTable.internChar16(cx, char16, len).unwrap() == ref); // Check concatenation works on empty atoms. const ParserAtom* concat[] = { @@ -58,16 +56,12 @@ 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.internChar16LE(cx, leTwoByte, 1).unwrap() == ref); const ParserAtom* concat[] = { ref, @@ -98,16 +92,12 @@ 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.internChar16LE(cx, leTwoByte, 2).unwrap() == ref); const ParserAtom* concat[] = { cx->parserNames().lookupTiny(ascii + 0, 1), diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index 5b5d83a7ad66..e8a58cf27325 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -843,8 +843,8 @@ ImmutableScriptData::ImmutableScriptData(uint32_t codeLength, } template -XDRResult js::XDRImmutableScriptData(XDRState* xdr, - UniquePtr& isd) { +static XDRResult XDRImmutableScriptData(XDRState* xdr, + UniquePtr& isd) { uint32_t codeLength = 0; uint32_t noteLength = 0; uint32_t numResumeOffsets = 0; @@ -914,11 +914,6 @@ XDRResult js::XDRImmutableScriptData(XDRState* xdr, return Ok(); } -template XDRResult js::XDRImmutableScriptData( - XDRState* xdr, UniquePtr& isd); -template XDRResult js::XDRImmutableScriptData( - XDRState* xdr, UniquePtr& isd); - template /* static */ XDRResult RuntimeScriptData::XDR(XDRState* xdr, HandleScript script) { diff --git a/js/src/vm/JSScript.h b/js/src/vm/JSScript.h index f55c06a6f397..7639ed9c0c4b 100644 --- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -1966,10 +1966,6 @@ XDRResult XDRLazyScript(XDRState* xdr, HandleScope enclosingScope, template XDRResult XDRSourceExtent(XDRState* xdr, SourceExtent* extent); -template -XDRResult XDRImmutableScriptData(XDRState* xdr, - UniquePtr& isd); - /* * Code any constant value. */ diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h index 8d55a74fef28..abd98249522a 100644 --- a/js/src/vm/Scope.h +++ b/js/src/vm/Scope.h @@ -81,7 +81,7 @@ class AbstractBindingName { template friend class AbstractBindingName; - // A JSAtom* or ParserAtom* with its low bit used as a tag for the: + // A JSAtom* with its low bit used as a tag for the: // * whether it is closed over (i.e., exists in the environment shape) // * whether it is a top-level function binding in global or eval scope, // instead of var binding (both are in the same range in Scope data) diff --git a/js/src/vm/Xdr.cpp b/js/src/vm/Xdr.cpp index e410b242cc49..19337dbc14cc 100644 --- a/js/src/vm/Xdr.cpp +++ b/js/src/vm/Xdr.cpp @@ -19,8 +19,7 @@ #include "builtin/ModuleObject.h" #include "debugger/DebugAPI.h" -#include "frontend/ParserAtom.h" // XDRParserAtom -#include "js/BuildId.h" // JS::BuildIdCharVector +#include "js/BuildId.h" // JS::BuildIdCharVector #include "vm/JSContext.h" #include "vm/JSScript.h" #include "vm/TraceLogging.h" @@ -282,22 +281,11 @@ static XDRResult AtomTable(XDRState* xdr) { MOZ_TRY(XDRAtomCount(xdr, &atomCount)); MOZ_ASSERT(!xdr->hasAtomTable()); - if (xdr->isForStencil()) { - for (uint32_t i = 0; i < atomCount; i++) { - const frontend::ParserAtom* atom = nullptr; - MOZ_TRY(XDRParserAtom(xdr, &atom)); - if (!xdr->parserAtomTable().append(atom)) { - ReportOutOfMemory(xdr->cx()); - return xdr->fail(JS::TranscodeResult_Throw); - } - } - } else { - for (uint32_t i = 0; i < atomCount; i++) { - RootedAtom atom(xdr->cx()); - MOZ_TRY(XDRAtom(xdr, &atom)); - if (!xdr->atomTable().append(atom)) { - return xdr->fail(JS::TranscodeResult_Throw); - } + for (uint32_t i = 0; i < atomCount; i++) { + RootedAtom atom(xdr->cx()); + MOZ_TRY(XDRAtom(xdr, &atom)); + if (!xdr->atomTable().append(atom)) { + return xdr->fail(JS::TranscodeResult_Throw); } } xdr->finishAtomTable(); @@ -376,30 +364,6 @@ XDRResult XDRState::codeScript(MutableHandleScript scriptp) { return Ok(); } -template -XDRResult XDRState::codeStencil(frontend::CompilationStencil& stencil) { -#ifdef DEBUG - auto sanityCheck = mozilla::MakeScopeExit( - [&] { MOZ_ASSERT(validateResultCode(cx(), resultCode())); }); -#endif - AutoXDRTree scriptTree(this, getTopLevelTreeKey()); - - // As with codeScript, use header buffer when incrementally encoding. - bool useHeader = this->hasAtomMap(); - if (useHeader) { - switchToHeaderBuf(); - } - MOZ_TRY(VersionCheck(this)); - MOZ_TRY(AtomTable(this)); - if (useHeader) { - switchToMainBuf(); - } - MOZ_ASSERT(isMainBuf()); - MOZ_TRY(XDRCompilationStencil(this, stencil)); - - return Ok(); -} - template class js::XDRState; template class js::XDRState; diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 93ff30a1e6ec..409436debb79 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -17,7 +17,6 @@ #include "jsfriendapi.h" #include "NamespaceImports.h" -#include "frontend/ParserAtom.h" #include "js/CompileOptions.h" #include "js/Transcoding.h" #include "js/TypeDecls.h" @@ -25,11 +24,6 @@ namespace js { -namespace frontend { -struct CompilationStencil; -struct CompilationInfo; -} // namespace frontend - class LifoAlloc; enum XDRMode { XDR_ENCODE, XDR_DECODE }; @@ -39,10 +33,6 @@ using XDRResult = mozilla::Result; using XDRAtomTable = JS::GCVector>; using XDRAtomMap = JS::GCHashMap, uint32_t>; -using XDRParserAtomTable = - Vector; -using XDRParserAtomMap = HashMap; - class XDRBufferBase { public: explicit XDRBufferBase(JSContext* cx, size_t cursor = 0) @@ -237,10 +227,6 @@ class XDRState : public XDRCoderBase { virtual ~XDRState() = default; JSContext* cx() const { return mainBuf.cx(); } - virtual bool isForStencil() const { return false; } - virtual frontend::CompilationInfo& stencilCompilationInfo() { - MOZ_CRASH("does not have stencil compilationInfo."); - } virtual bool hasOptions() const { return false; } virtual const JS::ReadOnlyCompileOptions& options() { @@ -253,21 +239,10 @@ class XDRState : public XDRCoderBase { virtual bool hasAtomMap() const { return false; } 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 bool hasAtomTable() const { return false; } virtual XDRAtomTable& atomTable() { MOZ_CRASH("does not have atomTable"); } - virtual frontend::ParserAtomsTable& frontendAtoms() { - MOZ_CRASH("does not have frontendAtoms"); - } - virtual XDRParserAtomTable& parserAtomTable() { - // This accessor is only used when encoding stencils. - MOZ_CRASH("does not have parserAtomTable"); - } virtual void finishAtomTable() { MOZ_CRASH("does not have atomTable"); } virtual bool isMainBuf() { return true; } @@ -450,7 +425,6 @@ class XDRState : public XDRCoderBase { XDRResult codeFunction(JS::MutableHandleFunction objp, HandleScriptSourceObject sourceObject = nullptr); XDRResult codeScript(MutableHandleScript scriptp); - XDRResult codeStencil(frontend::CompilationStencil& stencil); }; using XDREncoder = XDRState; @@ -476,47 +450,6 @@ class XDRDecoder : public XDRDecoderBase { bool hasFinishedAtomTable_ = false; }; -/* - * The stencil decoder accepts `options` and `range` as input, along - * with a freshly initialized `compilationInfo` and `parserAtoms` table. - * The decoded stencils are outputted to the default-initialized - * `compilationInfo` parameter, and decoded atoms are interned into - * the `parserAtoms` parameter. - */ -class XDRStencilDecoder : public XDRDecoderBase { - public: - XDRStencilDecoder(JSContext* cx, const JS::ReadOnlyCompileOptions* options, - const JS::TranscodeRange& range, - frontend::CompilationInfo& compilationInfo, - frontend::ParserAtomsTable& parserAtoms) - : XDRDecoderBase(cx, range), - options_(options), - compilationInfo_(compilationInfo), - parserAtoms_(parserAtoms) { - MOZ_ASSERT(options_); - } - - bool isForStencil() const override { return true; } - frontend::CompilationInfo& stencilCompilationInfo() override { - return compilationInfo_; - } - - bool hasAtomTable() const override { return hasFinishedAtomTable_; } - frontend::ParserAtomsTable& frontendAtoms() override { return parserAtoms_; } - XDRParserAtomTable& parserAtomTable() override { return parserAtomTable_; } - void finishAtomTable() override { hasFinishedAtomTable_ = true; } - - bool hasOptions() const override { return true; } - const JS::ReadOnlyCompileOptions& options() override { return *options_; } - - private: - const JS::ReadOnlyCompileOptions* options_; - XDRParserAtomTable parserAtomTable_; - bool hasFinishedAtomTable_ = false; - frontend::CompilationInfo& compilationInfo_; - frontend::ParserAtomsTable& parserAtoms_; -}; - class XDROffThreadDecoder : public XDRDecoder { const JS::ReadOnlyCompileOptions* options_; ScriptSourceObject** sourceObjectOut_; @@ -663,32 +596,6 @@ class XDRIncrementalEncoder : public XDREncoder { void trace(JSTracer* trc); }; -class XDRIncrementalStencilEncoder : public XDRIncrementalEncoder { - // The CompilationInfo for the compile. The main reason we keep a - // pointer to such a high-level struct within the encoder is to - // access the ScriptSource via `compilationInfo_.input`, as that - // needs to be encoded/decoded for XDR. - frontend::CompilationInfo& compilationInfo_; - - // Map from atoms to their index in the atom buffer - XDRParserAtomMap parserAtomMap_; - - public: - XDRIncrementalStencilEncoder(JSContext* cx, - frontend::CompilationInfo& compilationInfo) - : XDRIncrementalEncoder(cx), - compilationInfo_(compilationInfo), - parserAtomMap_(cx) {} - - virtual ~XDRIncrementalStencilEncoder() = default; - - bool isForStencil() const override { return true; } - frontend::CompilationInfo& stencilCompilationInfo() override { - return compilationInfo_; - } - XDRParserAtomMap& parserAtomMap() override { return parserAtomMap_; } -}; - template XDRResult XDRAtomOrNull(XDRState* xdr, js::MutableHandleAtom atomp); @@ -698,18 +605,6 @@ XDRResult XDRAtom(XDRState* xdr, js::MutableHandleAtom atomp); template XDRResult XDRAtomData(XDRState* xdr, js::MutableHandleAtom atomp); -template -XDRResult XDRParserAtom(XDRState* xdr, - const frontend::ParserAtom** atomp); - -template -XDRResult XDRParserAtomOrNull(XDRState* xdr, - const frontend::ParserAtom** atomp); - -template -XDRResult XDRCompilationStencil(XDRState* xdr, - frontend::CompilationStencil& stencil); - } /* namespace js */ #endif /* vm_Xdr_h */