Bug 1405661 - Baldr: decode Code section header in DecodeModuleEnvironment (r=lth)
authorLuke Wagner <luke@mozilla.com>
Thu, 05 Oct 2017 08:44:34 -0500
changeset 384692 13b556ec5a8e1adaabab213f987c437736f740b8
parent 384691 62fc2f51d566974bf2de7b93cf4588a2c2e81c4d
child 384693 afb1ab8386020882b1920b8015704f4e13ac4245
push id32634
push userkwierso@gmail.com
push dateFri, 06 Oct 2017 19:55:44 +0000
treeherdermozilla-central@2d7b8b5dd174 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1405661
milestone58.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
Bug 1405661 - Baldr: decode Code section header in DecodeModuleEnvironment (r=lth) MozReview-Commit-ID: ArNa3TgJk7l
js/src/wasm/WasmBinaryToAST.cpp
js/src/wasm/WasmCompile.cpp
js/src/wasm/WasmValidate.cpp
js/src/wasm/WasmValidate.h
--- a/js/src/wasm/WasmBinaryToAST.cpp
+++ b/js/src/wasm/WasmBinaryToAST.cpp
@@ -1794,20 +1794,17 @@ AstDecodeEnvironment(AstDecodeContext& c
         return false;
 
     return true;
 }
 
 static bool
 AstDecodeCodeSection(AstDecodeContext& c)
 {
-    MaybeSectionRange range;
-    if (!c.d.startSection(SectionId::Code, &c.env(), &range, "code"))
-        return false;
-    if (!range) {
+    if (!c.env().codeSection) {
         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");
@@ -1818,17 +1815,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(*range, "code");
+    return c.d.finishSection(*c.env().codeSection, "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,20 @@ 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)
 {
-    MaybeSectionRange range;
-    if (!d.startSection(SectionId::Code, env, &range, "code"))
-        return false;
-
     if (!mg.startFuncDefs())
         return false;
 
-    if (!range) {
+    if (!env->codeSection) {
         if (env->numFuncDefs() != 0)
             return d.fail("expected function bodies");
 
         return mg.finishFuncDefs();
     }
 
     uint32_t numFuncDefs;
     if (!d.readVarU32(&numFuncDefs))
@@ -75,17 +71,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(*range, "code"))
+    if (!d.finishSection(*env->codeSection, "code"))
         return false;
 
     return mg.finishFuncDefs();
 }
 
 bool
 CompileArgs::initFromContext(JSContext* cx, ScriptedCaller&& scriptedCaller)
 {
@@ -398,19 +394,17 @@ wasm::CompileInitialTier(const Shareable
     DebugEnabled debug = debugEnabled ? DebugEnabled::True : DebugEnabled::False;
 
     ModuleEnvironment env(ModuleEnvironment::UnknownMode, ModuleEnvironment::UnknownTier, debug);
 
     Decoder d(bytecode.bytes, error);
     if (!DecodeModuleEnvironment(d, &env))
         return nullptr;
 
-    uint32_t codeSize;
-    if (!d.peekSectionSize(SectionId::Code, &env, "code", &codeSize))
-        codeSize = 0;
+    uint32_t codeSize = env.codeSection ? env.codeSection->size : 0;
 
     CompileMode mode;
     Tier tier;
     if (baselineEnabled && ionEnabled && !debugEnabled && GetTieringEnabled(codeSize)) {
         mode = CompileMode::Tier1;
         tier = Tier::Baseline;
     } else {
         mode = CompileMode::Once;
--- a/js/src/wasm/WasmValidate.cpp
+++ b/js/src/wasm/WasmValidate.cpp
@@ -55,17 +55,17 @@ Decoder::fail(size_t errorOffset, const 
         return false;
 
     *error_ = Move(strWithOffset);
     return false;
 }
 
 bool
 Decoder::startSection(SectionId id, ModuleEnvironment* env, MaybeSectionRange* range,
-                      const char* sectionName, bool peeking)
+                      const char* sectionName)
 {
     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();
@@ -83,66 +83,47 @@ Decoder::startSection(SectionId id, Modu
     while (idValue != uint8_t(id)) {
         if (idValue != uint8_t(SectionId::Custom))
             goto rewind;
 
         // Rewind to the beginning of the current section since this is what
         // skipCustomSection() assumes.
         cur_ = currentSectionStart;
         if (!skipCustomSection(env)) {
-            if (peeking)
-                goto rewind;
             return false;
         }
 
         // Having successfully skipped a custom section, consider the next
         // section.
         currentSectionStart = cur_;
         if (!readFixedU8(&idValue))
             goto rewind;
     }
 
     // Found it, now start the section.
 
     uint32_t size;
-    if (!readVarU32(&size) || bytesRemain() < size) {
-        if (peeking)
-            goto rewind;
+    if (!readVarU32(&size) || bytesRemain() < size)
         goto fail;
-    }
 
     range->emplace();
     (*range)->start = cur_ - beg_;
     (*range)->size = size;
-    if (peeking)
-        goto rewind;
     return true;
 
   rewind:
     cur_ = initialCur;
     env->customSections.shrinkTo(initialCustomSectionsLength);
     return true;
 
   fail:
     return failf("failed to start %s section", sectionName);
 }
 
 bool
-Decoder::peekSectionSize(SectionId id, ModuleEnvironment* env, const char* sectionName, uint32_t* sectionSize)
-{
-    MaybeSectionRange range;
-    if (!startSection(id, env, &range, sectionName, /* peeking = */ true))
-        return false;
-    if (!range)
-        return false;
-    *sectionSize = range->size;
-    return true;
-}
-
-bool
 Decoder::finishSection(const SectionRange& range, const char* sectionName)
 {
     if (resilientMode_)
         return true;
     if (range.size != (cur_ - beg_) - range.start)
         return failf("byte size mismatch in %s section", sectionName);
     return true;
 }
@@ -1493,16 +1474,19 @@ wasm::DecodeModuleEnvironment(Decoder& d
         return false;
 
     if (!DecodeStartSection(d, env))
         return false;
 
     if (!DecodeElemSection(d, env))
         return false;
 
+    if (!d.startSection(SectionId::Code, env, &env->codeSection, "code"))
+        return false;
+
     return true;
 }
 
 static bool
 DecodeFunctionBody(Decoder& d, const ModuleEnvironment& env, uint32_t funcIndex)
 {
     uint32_t bodySize;
     if (!d.readVarU32(&bodySize))
@@ -1518,21 +1502,17 @@ DecodeFunctionBody(Decoder& d, const Mod
         return false;
 
     return true;
 }
 
 static bool
 DecodeCodeSection(Decoder& d, ModuleEnvironment* env)
 {
-    MaybeSectionRange range;
-    if (!d.startSection(SectionId::Code, env, &range, "code"))
-        return false;
-
-    if (!range) {
+    if (!env->codeSection) {
         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");
@@ -1540,17 +1520,17 @@ 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;
     }
 
-    return d.finishSection(*range, "code");
+    return d.finishSection(*env->codeSection, "code");
 }
 
 static bool
 DecodeDataSection(Decoder& d, ModuleEnvironment* env)
 {
     MaybeSectionRange range;
     if (!d.startSection(SectionId::Data, env, &range, "data"))
         return false;
--- a/js/src/wasm/WasmValidate.h
+++ b/js/src/wasm/WasmValidate.h
@@ -64,16 +64,17 @@ struct ModuleEnvironment
     SigWithIdPtrVector        funcSigs;
     Uint32Vector              funcImportGlobalDataOffsets;
     GlobalDescVector          globals;
     TableDescVector           tables;
     Uint32Vector              asmJSSigToTableIndex;
     ImportVector              imports;
     ExportVector              exports;
     Maybe<uint32_t>           startFuncIndex;
+    MaybeSectionRange         codeSection;
 
     // Fields decoded as part of the wasm module tail:
     ElemSegmentVector         elemSegments;
     DataSegmentVector         dataSegments;
     NameInBytecodeVector      funcNames;
     CustomSectionVector       customSections;
 
     static const CompileMode UnknownMode = (CompileMode)-1;
@@ -562,24 +563,19 @@ class Decoder
         return true;
     }
 
     // See "section" description in Encoder.
 
     MOZ_MUST_USE bool startSection(SectionId id,
                                    ModuleEnvironment* env,
                                    MaybeSectionRange* range,
-                                   const char* sectionName,
-                                   bool peeking = false);
+                                   const char* sectionName);
     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,
                                          MaybeSectionRange* range);