author | Luke Wagner <luke@mozilla.com> |
Thu, 05 Oct 2017 08:44:02 -0500 | |
changeset 384691 | 62fc2f51d566974bf2de7b93cf4588a2c2e81c4d |
parent 384690 | 0b50187d11f9299a66c2ea797943dcbb2a1ab2aa |
child 384692 | 13b556ec5a8e1adaabab213f987c437736f740b8 |
push id | 32634 |
push user | kwierso@gmail.com |
push date | Fri, 06 Oct 2017 19:55:44 +0000 |
treeherder | mozilla-central@2d7b8b5dd174 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | lth |
bugs | 1405661 |
milestone | 58.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/wasm/WasmBinaryToAST.cpp +++ b/js/src/wasm/WasmBinaryToAST.cpp @@ -1794,21 +1794,20 @@ AstDecodeEnvironment(AstDecodeContext& c return false; return true; } static bool AstDecodeCodeSection(AstDecodeContext& c) { - uint32_t sectionStart, sectionSize; - if (!c.d.startSection(SectionId::Code, &c.env(), §ionStart, §ionSize, "code")) + MaybeSectionRange range; + if (!c.d.startSection(SectionId::Code, &c.env(), &range, "code")) return false; - - if (sectionStart == Decoder::NotStarted) { + if (!range) { if (c.env().numFuncDefs() != 0) return c.d.fail("expected function bodies"); return true; } uint32_t numFuncBodies; if (!c.d.readVarU32(&numFuncBodies)) return c.d.fail("expected function body count"); @@ -1819,17 +1818,17 @@ AstDecodeCodeSection(AstDecodeContext& c for (uint32_t funcDefIndex = 0; funcDefIndex < numFuncBodies; funcDefIndex++) { AstFunc* func; if (!AstDecodeFunctionBody(c, c.module().numFuncImports() + funcDefIndex, &func)) return false; if (!c.module().append(func)) return false; } - return c.d.finishSection(sectionStart, sectionSize, "code"); + return c.d.finishSection(*range, "code"); } // Number of bytes to display in a single fragment of a data section (per line). static const size_t WRAP_DATA_BYTES = 30; static bool AstDecodeModuleTail(AstDecodeContext& c) {
--- a/js/src/wasm/WasmCompile.cpp +++ b/js/src/wasm/WasmCompile.cpp @@ -49,24 +49,24 @@ DecodeFunctionBody(Decoder& d, ModuleGen return d.fail("function body length too big"); return mg.compileFuncDef(funcIndex, offsetInModule, bodyBegin, bodyBegin + bodySize); } static bool DecodeCodeSection(Decoder& d, ModuleGenerator& mg, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Code, env, §ionStart, §ionSize, "code")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Code, env, &range, "code")) return false; if (!mg.startFuncDefs()) return false; - if (sectionStart == Decoder::NotStarted) { + if (!range) { if (env->numFuncDefs() != 0) return d.fail("expected function bodies"); return mg.finishFuncDefs(); } uint32_t numFuncDefs; if (!d.readVarU32(&numFuncDefs)) @@ -75,17 +75,17 @@ DecodeCodeSection(Decoder& d, ModuleGene if (numFuncDefs != env->numFuncDefs()) return d.fail("function body count does not match function signature count"); for (uint32_t funcDefIndex = 0; funcDefIndex < numFuncDefs; funcDefIndex++) { if (!DecodeFunctionBody(d, mg, env->numFuncImports() + funcDefIndex)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "code")) + if (!d.finishSection(*range, "code")) return false; return mg.finishFuncDefs(); } bool CompileArgs::initFromContext(JSContext* cx, ScriptedCaller&& scriptedCaller) {
--- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -54,19 +54,21 @@ Decoder::fail(size_t errorOffset, const if (!strWithOffset) return false; *error_ = Move(strWithOffset); return false; } bool -Decoder::startSection(SectionId id, ModuleEnvironment* env, uint32_t* sectionStart, - uint32_t* sectionSize, const char* sectionName, bool peeking) +Decoder::startSection(SectionId id, ModuleEnvironment* env, MaybeSectionRange* range, + const char* sectionName, bool peeking) { + MOZ_ASSERT(!*range); + // Record state at beginning of section to allow rewinding to this point // if, after skipping through several custom sections, we don't find the // section 'id'. const uint8_t* const initialCur = cur_; const size_t initialCustomSectionsLength = env->customSections.length(); // Maintain a pointer to the current section that gets updated as custom // sections are skipped. @@ -95,85 +97,87 @@ Decoder::startSection(SectionId id, Modu // section. currentSectionStart = cur_; if (!readFixedU8(&idValue)) goto rewind; } // Found it, now start the section. - if (!readVarU32(sectionSize) || bytesRemain() < *sectionSize) { + uint32_t size; + if (!readVarU32(&size) || bytesRemain() < size) { if (peeking) goto rewind; goto fail; } - *sectionStart = cur_ - beg_; + range->emplace(); + (*range)->start = cur_ - beg_; + (*range)->size = size; if (peeking) - goto rewind_peeking; + goto rewind; return true; rewind: - peeking = false; - rewind_peeking: cur_ = initialCur; env->customSections.shrinkTo(initialCustomSectionsLength); - if (!peeking) - *sectionStart = NotStarted; return true; fail: return failf("failed to start %s section", sectionName); } bool Decoder::peekSectionSize(SectionId id, ModuleEnvironment* env, const char* sectionName, uint32_t* sectionSize) { - uint32_t sectionStart; - if (!startSection(id, env, §ionStart, sectionSize, sectionName, /*peeking=*/true)) + MaybeSectionRange range; + if (!startSection(id, env, &range, sectionName, /* peeking = */ true)) return false; - return sectionStart != NotStarted; + if (!range) + return false; + *sectionSize = range->size; + return true; } bool -Decoder::finishSection(uint32_t sectionStart, uint32_t sectionSize, const char* sectionName) +Decoder::finishSection(const SectionRange& range, const char* sectionName) { if (resilientMode_) return true; - if (sectionSize != (cur_ - beg_) - sectionStart) + if (range.size != (cur_ - beg_) - range.start) return failf("byte size mismatch in %s section", sectionName); return true; } bool Decoder::startCustomSection(const char* expected, size_t expectedLength, ModuleEnvironment* env, - uint32_t* sectionStart, uint32_t* sectionSize) + MaybeSectionRange* range) { // Record state at beginning of section to allow rewinding to this point // if, after skipping through several custom sections, we don't find the // section 'id'. const uint8_t* const initialCur = cur_; const size_t initialCustomSectionsLength = env->customSections.length(); while (true) { // Try to start a custom section. If we can't, rewind to the beginning // since we may have skipped several custom sections already looking for // 'expected'. - if (!startSection(SectionId::Custom, env, sectionStart, sectionSize, "custom")) + if (!startSection(SectionId::Custom, env, range, "custom")) return false; - if (*sectionStart == NotStarted) + if (!*range) goto rewind; NameInBytecode name; if (!readVarU32(&name.length) || name.length > bytesRemain()) goto fail; name.offset = currentOffset(); uint32_t payloadOffset = name.offset + name.length; - uint32_t payloadEnd = *sectionStart + *sectionSize; + uint32_t payloadEnd = (*range)->start + (*range)->size; if (payloadOffset > payloadEnd) goto fail; // Now that we have a valid custom section, record its offsets in the // metadata which can be queried by the user via Module.customSections. // Note: after an entry is appended, it may be popped if this loop or // the loop in startSection needs to rewind. if (!env->customSections.emplaceBack(name, payloadOffset, payloadEnd - payloadOffset)) @@ -181,79 +185,80 @@ Decoder::startCustomSection(const char* // If this is the expected custom section, we're done. if (!expected || (expectedLength == name.length && !memcmp(cur_, expected, name.length))) { cur_ += name.length; return true; } // Otherwise, blindly skip the custom section and keep looking. - finishCustomSection(*sectionStart, *sectionSize); + finishCustomSection(**range); + range->reset(); } MOZ_CRASH("unreachable"); rewind: cur_ = initialCur; env->customSections.shrinkTo(initialCustomSectionsLength); return true; fail: return fail("failed to start custom section"); } void -Decoder::finishCustomSection(uint32_t sectionStart, uint32_t sectionSize) +Decoder::finishCustomSection(const SectionRange& range) { MOZ_ASSERT(cur_ >= beg_); MOZ_ASSERT(cur_ <= end_); - cur_ = (beg_ + sectionStart) + sectionSize; + cur_ = (beg_ + range.start) + range.size; MOZ_ASSERT(cur_ <= end_); clearError(); } bool Decoder::skipCustomSection(ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!startCustomSection(nullptr, 0, env, §ionStart, §ionSize)) + MaybeSectionRange range; + if (!startCustomSection(nullptr, 0, env, &range)) return false; - if (sectionStart == NotStarted) + if (!range) return fail("expected custom section"); - finishCustomSection(sectionStart, sectionSize); + finishCustomSection(*range); return true; } bool -Decoder::startNameSubsection(NameType nameType, uint32_t* endOffset) +Decoder::startNameSubsection(NameType nameType, Maybe<uint32_t>* endOffset) { + MOZ_ASSERT(!*endOffset); + const uint8_t* initialPosition = cur_; uint8_t nameTypeValue; if (!readFixedU8(&nameTypeValue)) return false; if (nameTypeValue != uint8_t(nameType)) { cur_ = initialPosition; - *endOffset = NotStarted; return true; } uint32_t payloadLength; if (!readVarU32(&payloadLength) || payloadLength > bytesRemain()) return false; - *endOffset = (cur_ - beg_) + payloadLength; + *endOffset = Some((cur_ - beg_) + payloadLength); return true; } bool Decoder::finishNameSubsection(uint32_t endOffset) { - MOZ_ASSERT(endOffset != NotStarted); return endOffset == uint32_t(cur_ - beg_); } // Misc helpers. bool wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals) { @@ -758,20 +763,20 @@ DecodePreamble(Decoder& d) } return true; } static bool DecodeTypeSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Type, env, §ionStart, §ionSize, "type")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Type, env, &range, "type")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numSigs; if (!d.readVarU32(&numSigs)) return d.fail("expected number of signatures"); if (numSigs > MaxTypes) return d.fail("too many signatures"); @@ -815,20 +820,17 @@ DecodeTypeSection(Decoder& d, ModuleEnvi return false; result = ToExprType(type); } env->sigs[sigIndex] = Sig(Move(args), result); } - if (!d.finishSection(sectionStart, sectionSize, "type")) - return false; - - return true; + return d.finishSection(*range, "type"); } static UniqueChars DecodeName(Decoder& d) { uint32_t numBytes; if (!d.readVarU32(&numBytes)) return nullptr; @@ -1050,51 +1052,51 @@ DecodeImport(Decoder& d, ModuleEnvironme } return env->imports.emplaceBack(Move(moduleName), Move(funcName), importKind); } static bool DecodeImportSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Import, env, §ionStart, §ionSize, "import")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Import, env, &range, "import")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numImports; if (!d.readVarU32(&numImports)) return d.fail("failed to read number of imports"); if (numImports > MaxImports) return d.fail("too many imports"); for (uint32_t i = 0; i < numImports; i++) { if (!DecodeImport(d, env)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "import")) + if (!d.finishSection(*range, "import")) return false; // The global data offsets will be filled in by ModuleGenerator::init. if (!env->funcImportGlobalDataOffsets.resize(env->funcSigs.length())) return false; return true; } static bool DecodeFunctionSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Function, env, §ionStart, §ionSize, "function")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Function, env, &range, "function")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numDefs; if (!d.readVarU32(&numDefs)) return d.fail("expected number of function definitions"); CheckedInt<uint32_t> numFuncs = env->funcSigs.length(); numFuncs += numDefs; @@ -1106,74 +1108,65 @@ DecodeFunctionSection(Decoder& d, Module for (uint32_t i = 0; i < numDefs; i++) { uint32_t sigIndex; if (!DecodeSignatureIndex(d, env->sigs, &sigIndex)) return false; env->funcSigs.infallibleAppend(&env->sigs[sigIndex]); } - if (!d.finishSection(sectionStart, sectionSize, "function")) - return false; - - return true; + return d.finishSection(*range, "function"); } static bool DecodeTableSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Table, env, §ionStart, §ionSize, "table")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Table, env, &range, "table")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numTables; if (!d.readVarU32(&numTables)) return d.fail("failed to read number of tables"); if (numTables > 1) return d.fail("the number of tables must be at most one"); for (uint32_t i = 0; i < numTables; ++i) { if (!DecodeTableLimits(d, &env->tables)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "table")) - return false; - - return true; + return d.finishSection(*range, "table"); } static bool DecodeMemorySection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Memory, env, §ionStart, §ionSize, "memory")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Memory, env, &range, "memory")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numMemories; if (!d.readVarU32(&numMemories)) return d.fail("failed to read number of memories"); if (numMemories > 1) return d.fail("the number of memories must be at most one"); for (uint32_t i = 0; i < numMemories; ++i) { if (!DecodeMemoryLimits(d, env)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "memory")) - return false; - - return true; + return d.finishSection(*range, "memory"); } static bool DecodeInitializerExpression(Decoder& d, const GlobalDescVector& globals, ValType expected, InitExpr* init) { OpBytes op; if (!d.readOp(&op)) @@ -1232,20 +1225,20 @@ DecodeInitializerExpression(Decoder& d, return d.fail("failed to read end of initializer expression"); return true; } static bool DecodeGlobalSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Global, env, §ionStart, §ionSize, "global")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Global, env, &range, "global")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numDefs; if (!d.readVarU32(&numDefs)) return d.fail("expected number of globals"); CheckedInt<uint32_t> numGlobals = env->globals.length(); numGlobals += numDefs; @@ -1263,20 +1256,17 @@ DecodeGlobalSection(Decoder& d, ModuleEn InitExpr initializer; if (!DecodeInitializerExpression(d, env->globals, type, &initializer)) return false; env->globals.infallibleAppend(GlobalDesc(initializer, isMutable)); } - if (!d.finishSection(sectionStart, sectionSize, "global")) - return false; - - return true; + return d.finishSection(*range, "global"); } typedef HashSet<const char*, CStringHasher, SystemAllocPolicy> CStringSet; static UniqueChars DecodeExportName(Decoder& d, CStringSet* dupSet) { UniqueChars exportName = DecodeName(d); @@ -1361,20 +1351,20 @@ DecodeExport(Decoder& d, ModuleEnvironme } MOZ_CRASH("unreachable"); } static bool DecodeExportSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Export, env, §ionStart, §ionSize, "export")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Export, env, &range, "export")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; CStringSet dupSet; if (!dupSet.init()) return false; uint32_t numExports; if (!d.readVarU32(&numExports)) @@ -1383,29 +1373,26 @@ DecodeExportSection(Decoder& d, ModuleEn if (numExports > MaxExports) return d.fail("too many exports"); for (uint32_t i = 0; i < numExports; i++) { if (!DecodeExport(d, env, &dupSet)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "export")) - return false; - - return true; + return d.finishSection(*range, "export"); } static bool DecodeStartSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Start, env, §ionStart, §ionSize, "start")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Start, env, &range, "start")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t funcIndex; if (!d.readVarU32(&funcIndex)) return d.fail("failed to read start func index"); if (funcIndex >= env->numFuncs()) return d.fail("unknown start function"); @@ -1414,29 +1401,26 @@ DecodeStartSection(Decoder& d, ModuleEnv if (!IsVoid(sig.ret())) return d.fail("start function must not return anything"); if (sig.args().length()) return d.fail("start function must be nullary"); env->startFuncIndex = Some(funcIndex); - if (!d.finishSection(sectionStart, sectionSize, "start")) - return false; - - return true; + return d.finishSection(*range, "start"); } static bool DecodeElemSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Elem, env, §ionStart, §ionSize, "elem")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Elem, env, &range, "elem")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numSegments; if (!d.readVarU32(&numSegments)) return d.fail("failed to read number of elem segments"); if (numSegments > MaxElemSegments) return d.fail("too many elem segments"); @@ -1473,20 +1457,17 @@ DecodeElemSection(Decoder& d, ModuleEnvi } if (!env->elemSegments.emplaceBack(0, offset, Move(elemFuncIndices))) return false; env->tables[env->elemSegments.back().tableIndex].external = true; } - if (!d.finishSection(sectionStart, sectionSize, "elem")) - return false; - - return true; + return d.finishSection(*range, "elem"); } bool wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env) { if (!DecodePreamble(d)) return false; @@ -1537,21 +1518,21 @@ DecodeFunctionBody(Decoder& d, const Mod return false; return true; } static bool DecodeCodeSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Code, env, §ionStart, §ionSize, "code")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Code, env, &range, "code")) return false; - if (sectionStart == Decoder::NotStarted) { + if (!range) { if (env->numFuncDefs() != 0) return d.fail("expected function bodies"); return true; } uint32_t numFuncDefs; if (!d.readVarU32(&numFuncDefs)) return d.fail("expected function body count"); @@ -1559,29 +1540,26 @@ DecodeCodeSection(Decoder& d, ModuleEnvi if (numFuncDefs != env->numFuncDefs()) return d.fail("function body count does not match function signature count"); for (uint32_t funcDefIndex = 0; funcDefIndex < numFuncDefs; funcDefIndex++) { if (!DecodeFunctionBody(d, *env, env->numFuncImports() + funcDefIndex)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "code")) - return false; - - return true; + return d.finishSection(*range, "code"); } static bool DecodeDataSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startSection(SectionId::Data, env, §ionStart, §ionSize, "data")) + MaybeSectionRange range; + if (!d.startSection(SectionId::Data, env, &range, "data")) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; uint32_t numSegments; if (!d.readVarU32(&numSegments)) return d.fail("failed to read number of data segments"); if (numSegments > MaxDataSegments) return d.fail("too many data segments"); @@ -1611,29 +1589,26 @@ DecodeDataSection(Decoder& d, ModuleEnvi if (!d.readBytes(seg.length)) return d.fail("data segment shorter than declared"); if (!env->dataSegments.append(seg)) return false; } - if (!d.finishSection(sectionStart, sectionSize, "data")) - return false; - - return true; + return d.finishSection(*range, "data"); } static bool DecodeModuleNameSubsection(Decoder& d, ModuleEnvironment* env) { - uint32_t endOffset; + Maybe<uint32_t> endOffset; if (!d.startNameSubsection(NameType::Module, &endOffset)) return false; - if (endOffset == Decoder::NotStarted) + if (!endOffset) return true; // Don't use NameInBytecode for module name; instead store a copy of the // string. This way supplying a module name doesn't need to save the whole // bytecode. While function names are likely to be stripped in practice, // module names aren't necessarily. uint32_t nameLength; @@ -1642,26 +1617,26 @@ DecodeModuleNameSubsection(Decoder& d, M const uint8_t* bytes; if (!d.readBytes(nameLength, &bytes)) return false; // Do nothing with module name for now; a future patch will incorporate the // module name into the callstack format. - return d.finishNameSubsection(endOffset); + return d.finishNameSubsection(*endOffset); } static bool DecodeFunctionNameSubsection(Decoder& d, ModuleEnvironment* env) { - uint32_t endOffset; + Maybe<uint32_t> endOffset; if (!d.startNameSubsection(NameType::Function, &endOffset)) return false; - if (endOffset == Decoder::NotStarted) + if (!endOffset) return true; uint32_t nameCount = 0; if (!d.readVarU32(&nameCount) || nameCount > MaxFuncs) return false; NameInBytecodeVector funcNames; @@ -1685,48 +1660,48 @@ DecodeFunctionNameSubsection(Decoder& d, return false; funcNames[funcIndex] = NameInBytecode(d.currentOffset(), nameLength); if (!d.readBytes(nameLength)) return false; } - if (!d.finishNameSubsection(endOffset)) + if (!d.finishNameSubsection(*endOffset)) return false; // To encourage fully valid function names subsections; only save names if // the entire subsection decoded correctly. env->funcNames = Move(funcNames); return true; } static bool DecodeNameSection(Decoder& d, ModuleEnvironment* env) { - uint32_t sectionStart, sectionSize; - if (!d.startCustomSection(NameSectionName, env, §ionStart, §ionSize)) + MaybeSectionRange range; + if (!d.startCustomSection(NameSectionName, env, &range)) return false; - if (sectionStart == Decoder::NotStarted) + if (!range) return true; // Once started, custom sections do not report validation errors. if (!DecodeModuleNameSubsection(d, env)) goto finish; if (!DecodeFunctionNameSubsection(d, env)) goto finish; // The names we care about have already been extracted into 'env' so don't // bother decoding the rest of the name section. finishCustomSection() will // skip to the end of the name section (as it would for any other error). finish: - d.finishCustomSection(sectionStart, sectionSize); + d.finishCustomSection(*range); return true; } bool wasm::DecodeModuleTail(Decoder& d, ModuleEnvironment* env) { if (!DecodeDataSection(d, env)) return false;
--- a/js/src/wasm/WasmValidate.h +++ b/js/src/wasm/WasmValidate.h @@ -20,16 +20,27 @@ #define wasm_validate_h #include "wasm/WasmCode.h" #include "wasm/WasmTypes.h" namespace js { namespace wasm { +// This struct captures the bytecode offset of a section's payload (so not +// including the header) and the size of the payload. + +struct SectionRange +{ + uint32_t start; + uint32_t size; +}; + +typedef Maybe<SectionRange> MaybeSectionRange; + // ModuleEnvironment contains all the state necessary to validate, process or // render functions. It is created by decoding all the sections before the wasm // code section and then used immutably during. When compiling a module using a // ModuleGenerator, the ModuleEnvironment holds state shared between the // ModuleGenerator thread and background compile threads. All the threads // are given a read-only view of the ModuleEnvironment, thus preventing race // conditions. @@ -548,56 +559,49 @@ class Decoder if (bytesRemain() < numBytes) return false; cur_ += numBytes; return true; } // See "section" description in Encoder. - static const uint32_t NotStarted = UINT32_MAX; - MOZ_MUST_USE bool startSection(SectionId id, ModuleEnvironment* env, - uint32_t* sectionStart, - uint32_t* sectionSize, + MaybeSectionRange* range, const char* sectionName, bool peeking = false); - MOZ_MUST_USE bool finishSection(uint32_t sectionStart, - uint32_t sectionSize, + MOZ_MUST_USE bool finishSection(const SectionRange& range, const char* sectionName); MOZ_MUST_USE bool peekSectionSize(SectionId id, ModuleEnvironment* env, const char* sectionName, uint32_t* sectionSize); // Custom sections do not cause validation errors unless the error is in // the section header itself. MOZ_MUST_USE bool startCustomSection(const char* expected, size_t expectedLength, ModuleEnvironment* env, - uint32_t* sectionStart, - uint32_t* sectionSize); + MaybeSectionRange* range); template <size_t NameSizeWith0> MOZ_MUST_USE bool startCustomSection(const char (&name)[NameSizeWith0], ModuleEnvironment* env, - uint32_t* sectionStart, - uint32_t* sectionSize) + MaybeSectionRange* range) { MOZ_ASSERT(name[NameSizeWith0 - 1] == '\0'); - return startCustomSection(name, NameSizeWith0 - 1, env, sectionStart, sectionSize); + return startCustomSection(name, NameSizeWith0 - 1, env, range); } - void finishCustomSection(uint32_t sectionStart, uint32_t sectionSize); + void finishCustomSection(const SectionRange& range); MOZ_MUST_USE bool skipCustomSection(ModuleEnvironment* env); - // The Name section has its own subsections. Like startSection, NotStart is - // returned as the endOffset if the given name subsection wasn't present. + // The Name section has its own optional subsections. - MOZ_MUST_USE bool startNameSubsection(NameType nameType, uint32_t* endOffset); + MOZ_MUST_USE bool startNameSubsection(NameType nameType, Maybe<uint32_t>* endOffset); MOZ_MUST_USE bool finishNameSubsection(uint32_t endOffset); // The infallible "unchecked" decoding functions can be used when we are // sure that the bytes are well-formed (by construction or due to previous // validation). uint8_t uncheckedReadFixedU8() { return uncheckedRead<uint8_t>();