Bug 1316635: Factor out DecodeFunctionSection; r=luke
authorBenjamin Bouvier <benj@benj.me>
Thu, 10 Nov 2016 18:26:25 +0100
changeset 322148 aed62b2e0a8a14845fcc975ed70874dc6bd46f1c
parent 322147 5227163b9dad33c56cc657bc847cb534ed3141ef
child 322149 4ad7c2178c63b45d970b85227ef228d1a21c2a28
push id21
push usermaklebus@msu.edu
push dateThu, 01 Dec 2016 06:22:08 +0000
reviewersluke
bugs1316635
milestone52.0a1
Bug 1316635: Factor out DecodeFunctionSection; r=luke MozReview-Commit-ID: Ef8QRIPjbID
js/src/wasm/WasmAST.h
js/src/wasm/WasmBinaryFormat.cpp
js/src/wasm/WasmBinaryFormat.h
js/src/wasm/WasmBinaryToAST.cpp
js/src/wasm/WasmCompile.cpp
--- a/js/src/wasm/WasmAST.h
+++ b/js/src/wasm/WasmAST.h
@@ -893,16 +893,19 @@ class AstModule : public AstNode
         return imports_.append(imp);
     }
     const ImportVector& imports() const {
         return imports_;
     }
     const NameVector& funcImportNames() const {
         return funcImportNames_;
     }
+    size_t numFuncImports() const {
+        return funcImportNames_.length();
+    }
     bool append(AstExport* exp) {
         return exports_.append(exp);
     }
     const ExportVector& exports() const {
         return exports_;
     }
     bool append(AstGlobal* glob) {
         return globals_.append(glob);
--- a/js/src/wasm/WasmBinaryFormat.cpp
+++ b/js/src/wasm/WasmBinaryFormat.cpp
@@ -149,18 +149,18 @@ wasm::DecodeName(Decoder& d)
         return nullptr;
 
     memcpy(name.get(), bytes, numBytes);
     name[numBytes] = '\0';
 
     return name;
 }
 
-bool
-wasm::DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex)
+static bool
+DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex)
 {
     if (!d.readVarU32(sigIndex))
         return d.fail("expected signature index");
 
     if (*sigIndex >= sigs.length())
         return d.fail("signature index out of range");
 
     return true;
@@ -291,16 +291,50 @@ wasm::DecodeImportSection(Decoder& d, co
 
     if (!d.finishSection(sectionStart, sectionSize, "import"))
         return false;
 
     return true;
 }
 
 bool
+wasm::DecodeFunctionSection(Decoder& d, const SigWithIdVector& sigs, size_t numImportedFunc,
+                            Uint32Vector* funcSigIndexes)
+{
+    uint32_t sectionStart, sectionSize;
+    if (!d.startSection(SectionId::Function, &sectionStart, &sectionSize, "function"))
+        return false;
+    if (sectionStart == Decoder::NotStarted)
+        return true;
+
+    uint32_t numDefs;
+    if (!d.readVarU32(&numDefs))
+        return d.fail("expected number of function definitions");
+
+    uint32_t numFuncs = numImportedFunc + numDefs;
+    if (numFuncs > MaxFuncs)
+        return d.fail("too many functions");
+
+    if (!funcSigIndexes->reserve(numDefs))
+        return false;
+
+    for (uint32_t i = 0; i < numDefs; i++) {
+        uint32_t sigIndex;
+        if (!DecodeSignatureIndex(d, sigs, &sigIndex))
+            return false;
+        funcSigIndexes->infallibleAppend(sigIndex);
+    }
+
+    if (!d.finishSection(sectionStart, sectionSize, "function"))
+        return false;
+
+    return true;
+}
+
+bool
 wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals)
 {
     uint32_t numLocalEntries = 0;
     ValType prev = ValType(TypeCode::Limit);
     for (ValType t : locals) {
         if (t != prev) {
             numLocalEntries++;
             prev = t;
--- a/js/src/wasm/WasmBinaryFormat.h
+++ b/js/src/wasm/WasmBinaryFormat.h
@@ -643,30 +643,31 @@ CheckValType(Decoder& d, ValType type);
 
 MOZ_MUST_USE bool
 DecodeTypeSection(Decoder& d, SigWithIdVector* sigs);
 
 UniqueChars
 DecodeName(Decoder& d);
 
 MOZ_MUST_USE bool
-DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex);
-
-MOZ_MUST_USE bool
 DecodeTableLimits(Decoder& d, TableDescVector* tables);
 
 MOZ_MUST_USE bool
 GlobalIsJSCompatible(Decoder& d, ValType type, bool isMutable);
 
 MOZ_MUST_USE bool
 DecodeImportSection(Decoder& d, const SigWithIdVector& sigs, Uint32Vector* funcSigIndices,
                     GlobalDescVector* globals, TableDescVector* tables, Maybe<Limits>* memory,
                     ImportVector* imports);
 
 MOZ_MUST_USE bool
+DecodeFunctionSection(Decoder& d, const SigWithIdVector& sigs, size_t numImportedFunc,
+                      Uint32Vector* funcSigIndexes);
+
+MOZ_MUST_USE bool
 EncodeLocalEntries(Encoder& d, const ValTypeVector& locals);
 
 MOZ_MUST_USE bool
 DecodeLocalEntries(Decoder& d, ValTypeVector* locals);
 
 MOZ_MUST_USE bool
 DecodeGlobalType(Decoder& d, ValType* type, bool* isMutable);
 
--- a/js/src/wasm/WasmBinaryToAST.cpp
+++ b/js/src/wasm/WasmBinaryToAST.cpp
@@ -326,22 +326,22 @@ AstDecodeCall(AstDecodeContext& c)
     if (!c.iter().readCall(&funcIndex))
         return false;
 
     if (!c.iter().inReachableCode())
         return true;
 
     uint32_t sigIndex;
     AstRef funcRef;
-    if (funcIndex < c.module().funcImportNames().length()) {
+    if (funcIndex < c.module().numFuncImports()) {
         AstImport* import = c.module().imports()[funcIndex];
         sigIndex = import->funcSig().index();
         funcRef = AstRef(import->name());
     } else {
-        uint32_t funcDefIndex = funcIndex - c.module().funcImportNames().length();
+        uint32_t funcDefIndex = funcIndex - c.module().numFuncImports();
         if (funcDefIndex >= c.funcDefSigs().length())
             return c.iter().fail("callee index out of range");
 
         sigIndex = c.funcDefSigs()[funcDefIndex];
 
         if (!AstDecodeGenerateRef(c, AstName(u"func"), funcIndex, &funcRef))
             return false;
     }
@@ -1550,55 +1550,23 @@ AstDecodeImportSection(AstDecodeContext&
         if (!ast || !c.module().append(ast))
             return false;
     }
 
     return true;
 }
 
 static bool
-AstDecodeSignatureIndex(AstDecodeContext& c, uint32_t* sigIndex)
-{
-    if (!c.d.readVarU32(sigIndex))
-        return c.d.fail("expected signature index");
-
-    if (*sigIndex >= c.module().sigs().length())
-        return c.d.fail("signature index out of range");
-
-    return true;
-}
-
-static bool
-AstDecodeFunctionSection(AstDecodeContext& c)
+AstDecodeFunctionSection(AstDecodeContext& c, const SigWithIdVector& sigs)
 {
-    uint32_t sectionStart, sectionSize;
-    if (!c.d.startSection(SectionId::Function, &sectionStart, &sectionSize, "function"))
-        return false;
-    if (sectionStart == Decoder::NotStarted)
-        return true;
-
-    uint32_t numDecls;
-    if (!c.d.readVarU32(&numDecls))
-        return c.d.fail("expected number of declarations");
-
-    if (numDecls > MaxFuncs)
-        return c.d.fail("too many functions");
-
-    if (!c.funcDefSigs().resize(numDecls))
+    Uint32Vector funcSigIndexes;
+    if (!DecodeFunctionSection(c.d, sigs, c.module().numFuncImports(), &funcSigIndexes))
         return false;
 
-    for (uint32_t i = 0; i < numDecls; i++) {
-        if (!AstDecodeSignatureIndex(c, &c.funcDefSigs()[i]))
-            return false;
-    }
-
-    if (!c.d.finishSection(sectionStart, sectionSize, "function"))
-        return false;
-
-    return true;
+    return c.funcDefSigs().appendAll(funcSigIndexes);
 }
 
 static bool
 AstDecodeTableSection(AstDecodeContext& c)
 {
     uint32_t sectionStart, sectionSize;
     if (!c.d.startSection(SectionId::Table, &sectionStart, &sectionSize, "table"))
         return false;
@@ -1841,17 +1809,17 @@ AstDecodeFunctionBody(AstDecodeContext &
 
     if (!DecodeLocalEntries(c.d, &locals))
         return c.d.fail("failed decoding local entries");
 
     c.startFunction(&iter, &locals, sig->ret());
 
     AstName funcName;
     if (!AstDecodeGenerateName(c, AstName(u"func"),
-                               c.module().funcImportNames().length() + funcDefIndex,
+                               c.module().numFuncImports() + funcDefIndex,
                                &funcName))
         return false;
 
     uint32_t numParams = sig->args().length();
     uint32_t numLocals = locals.length();
     for (uint32_t i = numParams; i < numLocals; i++) {
         if (!vars.append(locals[i]))
             return false;
@@ -2071,17 +2039,17 @@ wasm::BinaryToAst(JSContext* cx, const u
     UniqueChars error;
     Decoder d(bytes, bytes + length, &error);
     AstDecodeContext c(cx, lifo, d, *result, true);
 
     SigWithIdVector sigs;
     if (!DecodePreamble(d) ||
         !AstDecodeTypeSection(c, &sigs) ||
         !AstDecodeImportSection(c, sigs) ||
-        !AstDecodeFunctionSection(c) ||
+        !AstDecodeFunctionSection(c, sigs) ||
         !AstDecodeTableSection(c) ||
         !AstDecodeMemorySection(c) ||
         !AstDecodeGlobalSection(c) ||
         !AstDecodeExportSection(c) ||
         !AstDecodeStartSection(c) ||
         !AstDecodeElemSection(c) ||
         !AstDecodeCodeSection(c) ||
         !AstDecodeDataSection(c) ||
--- a/js/src/wasm/WasmCompile.cpp
+++ b/js/src/wasm/WasmCompile.cpp
@@ -435,44 +435,25 @@ DecodeImportSection(Decoder& d, ModuleGe
     }
 
     return true;
 }
 
 static bool
 DecodeFunctionSection(Decoder& d, ModuleGeneratorData* init)
 {
-    uint32_t sectionStart, sectionSize;
-    if (!d.startSection(SectionId::Function, &sectionStart, &sectionSize, "function"))
-        return false;
-    if (sectionStart == Decoder::NotStarted)
-        return true;
-
-    uint32_t numDefs;
-    if (!d.readVarU32(&numDefs))
-        return d.fail("expected number of function definitions");
-
-    uint32_t numFuncs = init->funcSigs.length() + numDefs;
-    if (numFuncs > MaxFuncs)
-        return d.fail("too many functions");
-
-    if (!init->funcSigs.reserve(numFuncs))
+    Uint32Vector funcSigIndexes;
+    if (!DecodeFunctionSection(d, init->sigs, init->funcSigs.length(), &funcSigIndexes))
         return false;
 
-    for (uint32_t i = 0; i < numDefs; i++) {
-        uint32_t sigIndex;
-        if (!DecodeSignatureIndex(d, init->sigs, &sigIndex))
-            return false;
+    if (!init->funcSigs.reserve(init->funcSigs.length() + funcSigIndexes.length()))
+        return false;
 
-        const SigWithId* sig = &init->sigs[sigIndex];
-        init->funcSigs.infallibleAppend(sig);
-    }
-
-    if (!d.finishSection(sectionStart, sectionSize, "function"))
-        return false;
+    for (uint32_t sigIndex : funcSigIndexes)
+        init->funcSigs.infallibleAppend(&init->sigs[sigIndex]);
 
     return true;
 }
 
 static bool
 DecodeTableSection(Decoder& d, ModuleGeneratorData* init, Uint32Vector* oldElems)
 {
     uint32_t sectionStart, sectionSize;
@@ -938,17 +919,17 @@ wasm::Compile(const ShareableBytes& byte
 
     if (!DecodeTypeSection(d, &init->sigs))
         return nullptr;
 
     ImportVector imports;
     if (!::DecodeImportSection(d, init.get(), &imports))
         return nullptr;
 
-    if (!DecodeFunctionSection(d, init.get()))
+    if (!::DecodeFunctionSection(d, init.get()))
         return nullptr;
 
     Uint32Vector oldElems;
     if (!DecodeTableSection(d, init.get(), &oldElems))
         return nullptr;
 
     if (!::DecodeMemorySection(d, init.get()))
         return nullptr;