Bug 1316635: Factor out DecodeTypeSection; r?luke draft
authorBenjamin Bouvier <benj@benj.me>
Tue, 08 Nov 2016 18:22:47 +0100
changeset 437272 5055900e08d56e9c8744a91bb5df3a954c0f2ca2
parent 437169 a67f9e4b5faf56f66f454d58118cbea584a7f334
child 437273 c32693ea8288d84e29cef231b142cccc6fd04845
push id35371
push userbbouvier@mozilla.com
push dateThu, 10 Nov 2016 17:45:13 +0000
reviewersluke
bugs1316635
milestone52.0a1
Bug 1316635: Factor out DecodeTypeSection; r?luke MozReview-Commit-ID: HOaUFi8npPN
js/src/wasm/WasmBinaryFormat.cpp
js/src/wasm/WasmBinaryFormat.h
js/src/wasm/WasmBinaryToAST.cpp
js/src/wasm/WasmCompile.cpp
--- a/js/src/wasm/WasmBinaryFormat.cpp
+++ b/js/src/wasm/WasmBinaryFormat.cpp
@@ -37,16 +37,106 @@ wasm::DecodePreamble(Decoder& d)
     if (!d.readFixedU32(&u32) || u32 != EncodingVersion)
         return d.fail("binary version 0x%" PRIx32 " does not match expected version 0x%" PRIx32,
                       u32, EncodingVersion);
 
     return true;
 }
 
 bool
+wasm::CheckValType(Decoder& d, ValType type)
+{
+    switch (type) {
+      case ValType::I32:
+      case ValType::F32:
+      case ValType::F64:
+      case ValType::I64:
+        return true;
+      default:
+        // Note: it's important not to remove this default since readValType()
+        // can return ValType values for which there is no enumerator.
+        break;
+    }
+
+    return d.fail("bad type");
+}
+
+bool
+wasm::DecodeTypeSection(Decoder& d, SigWithIdVector* sigs)
+{
+    uint32_t sectionStart, sectionSize;
+    if (!d.startSection(SectionId::Type, &sectionStart, &sectionSize, "type"))
+        return false;
+    if (sectionStart == Decoder::NotStarted)
+        return true;
+
+    uint32_t numSigs;
+    if (!d.readVarU32(&numSigs))
+        return d.fail("expected number of signatures");
+
+    if (numSigs > MaxSigs)
+        return d.fail("too many signatures");
+
+    if (!sigs->resize(numSigs))
+        return false;
+
+    for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
+        uint32_t form;
+        if (!d.readVarU32(&form) || form != uint32_t(TypeCode::Func))
+            return d.fail("expected function form");
+
+        uint32_t numArgs;
+        if (!d.readVarU32(&numArgs))
+            return d.fail("bad number of function args");
+
+        if (numArgs > MaxArgsPerFunc)
+            return d.fail("too many arguments in signature");
+
+        ValTypeVector args;
+        if (!args.resize(numArgs))
+            return false;
+
+        for (uint32_t i = 0; i < numArgs; i++) {
+            if (!d.readValType(&args[i]))
+                return d.fail("bad value type");
+
+            if (!CheckValType(d, args[i]))
+                return false;
+        }
+
+        uint32_t numRets;
+        if (!d.readVarU32(&numRets))
+            return d.fail("bad number of function returns");
+
+        if (numRets > 1)
+            return d.fail("too many returns in signature");
+
+        ExprType result = ExprType::Void;
+
+        if (numRets == 1) {
+            ValType type;
+            if (!d.readValType(&type))
+                return d.fail("bad expression type");
+
+            if (!CheckValType(d, type))
+                return false;
+
+            result = ToExprType(type);
+        }
+
+        (*sigs)[sigIndex] = Sig(Move(args), result);
+    }
+
+    if (!d.finishSection(sectionStart, sectionSize, "type"))
+        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
@@ -28,16 +28,22 @@ namespace wasm {
 // Reusable macro encoding/decoding functions reused by both the two
 // encoders (AsmJS/WasmTextToBinary) and all the decoders
 // (WasmCompile/WasmIonCompile/WasmBaselineCompile/WasmBinaryToText).
 
 MOZ_MUST_USE bool
 DecodePreamble(Decoder& d);
 
 MOZ_MUST_USE bool
+CheckValType(Decoder& d, ValType type);
+
+MOZ_MUST_USE bool
+DecodeTypeSection(Decoder& d, SigWithIdVector* sigs);
+
+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
@@ -1429,80 +1429,37 @@ AstDecodeExpr(AstDecodeContext& c)
 }
 
 /*****************************************************************************/
 // wasm decoding and generation
 
 static bool
 AstDecodeTypeSection(AstDecodeContext& c)
 {
-    uint32_t sectionStart, sectionSize;
-    if (!c.d.startSection(SectionId::Type, &sectionStart, &sectionSize, "type"))
+    SigWithIdVector sigs;
+    if (!DecodeTypeSection(c.d, &sigs))
         return false;
-    if (sectionStart == Decoder::NotStarted)
-        return true;
-
-    uint32_t numSigs;
-    if (!c.d.readVarU32(&numSigs))
-        return c.d.fail("expected number of signatures");
 
-    if (numSigs > MaxSigs)
-        return c.d.fail("too many signatures");
-
-    for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
-        uint32_t form;
-        if (!c.d.readVarU32(&form) || form != uint32_t(TypeCode::Func))
-            return c.d.fail("expected function form");
-
-        uint32_t numArgs;
-        if (!c.d.readVarU32(&numArgs))
-            return c.d.fail("bad number of function args");
-
-        if (numArgs > MaxArgsPerFunc)
-            return c.d.fail("too many arguments in signature");
+    for (size_t sigIndex = 0; sigIndex < sigs.length(); sigIndex++) {
+        const Sig& sig = sigs[sigIndex];
 
         AstValTypeVector args(c.lifo);
-        if (!args.resize(numArgs))
+        if (!args.appendAll(sig.args()))
             return false;
 
-        for (uint32_t i = 0; i < numArgs; i++) {
-            if (!c.d.readValType(&args[i]))
-                return c.d.fail("bad value type");
-        }
-
-        uint32_t numRets;
-        if (!c.d.readVarU32(&numRets))
-            return c.d.fail("bad number of function returns");
-
-        if (numRets > 1)
-            return c.d.fail("too many returns in signature");
-
-        ExprType result = ExprType::Void;
-
-        if (numRets == 1) {
-            ValType type;
-            if (!c.d.readValType(&type))
-                return c.d.fail("bad expression type");
-
-            result = ToExprType(type);
-        }
-
-        AstSig sigNoName(Move(args), result);
+        AstSig sigNoName(Move(args), sig.ret());
         AstName sigName;
         if (!AstDecodeGenerateName(c, AstName(u"type"), sigIndex, &sigName))
             return false;
 
-        AstSig* sig = new(c.lifo) AstSig(sigName, Move(sigNoName));
-        if (!sig || !c.module().append(sig))
+        AstSig* astSig = new(c.lifo) AstSig(sigName, Move(sigNoName));
+        if (!astSig || !c.module().append(astSig))
             return false;
     }
 
-    if (!c.d.finishSection(sectionStart, sectionSize, "type"))
-        return false;
-
     return true;
 }
 
 static bool
 AstDecodeSignatureIndex(AstDecodeContext& c, uint32_t* sigIndex)
 {
     if (!c.d.readVarU32(sigIndex))
         return c.d.fail("expected signature index");
--- a/js/src/wasm/WasmCompile.cpp
+++ b/js/src/wasm/WasmCompile.cpp
@@ -60,34 +60,16 @@ class FunctionDecoder
             return iter().fail("can't touch memory without memory");
         return true;
     }
 };
 
 } // end anonymous namespace
 
 static bool
-CheckValType(Decoder& d, ValType type)
-{
-    switch (type) {
-      case ValType::I32:
-      case ValType::F32:
-      case ValType::F64:
-      case ValType::I64:
-        return true;
-      default:
-        // Note: it's important not to remove this default since readValType()
-        // can return ValType values for which there is no enumerator.
-        break;
-    }
-
-    return d.fail("bad type");
-}
-
-static bool
 DecodeCallArgs(FunctionDecoder& f, const Sig& sig)
 {
     const ValTypeVector& args = sig.args();
     uint32_t numArgs = args.length();
     for (size_t i = 0; i < numArgs; ++i) {
         ValType argType = args[i];
         if (!f.iter().readCallArg(argType, numArgs, i, nullptr))
             return false;
@@ -424,88 +406,16 @@ DecodeFunctionBodyExprs(FunctionDecoder&
     }
 
     MOZ_CRASH("unreachable");
 
 #undef CHECK
 }
 
 static bool
-DecodeTypeSection(Decoder& d, ModuleGeneratorData* init)
-{
-    uint32_t sectionStart, sectionSize;
-    if (!d.startSection(SectionId::Type, &sectionStart, &sectionSize, "type"))
-        return false;
-    if (sectionStart == Decoder::NotStarted)
-        return true;
-
-    uint32_t numSigs;
-    if (!d.readVarU32(&numSigs))
-        return d.fail("expected number of signatures");
-
-    if (numSigs > MaxSigs)
-        return d.fail("too many signatures");
-
-    if (!init->sigs.resize(numSigs))
-        return false;
-
-    for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
-        uint32_t form;
-        if (!d.readVarU32(&form) || form != uint32_t(TypeCode::Func))
-            return d.fail("expected function form");
-
-        uint32_t numArgs;
-        if (!d.readVarU32(&numArgs))
-            return d.fail("bad number of function args");
-
-        if (numArgs > MaxArgsPerFunc)
-            return d.fail("too many arguments in signature");
-
-        ValTypeVector args;
-        if (!args.resize(numArgs))
-            return false;
-
-        for (uint32_t i = 0; i < numArgs; i++) {
-            if (!d.readValType(&args[i]))
-                return d.fail("bad value type");
-
-            if (!CheckValType(d, args[i]))
-                return false;
-        }
-
-        uint32_t numRets;
-        if (!d.readVarU32(&numRets))
-            return d.fail("bad number of function returns");
-
-        if (numRets > 1)
-            return d.fail("too many returns in signature");
-
-        ExprType result = ExprType::Void;
-
-        if (numRets == 1) {
-            ValType type;
-            if (!d.readValType(&type))
-                return d.fail("bad expression type");
-
-            if (!CheckValType(d, type))
-                return false;
-
-            result = ToExprType(type);
-        }
-
-        init->sigs[sigIndex] = Sig(Move(args), result);
-    }
-
-    if (!d.finishSection(sectionStart, sectionSize, "type"))
-        return false;
-
-    return true;
-}
-
-static bool
 DecodeSignatureIndex(Decoder& d, const ModuleGeneratorData& init, const SigWithId** sig)
 {
     uint32_t sigIndex;
     if (!d.readVarU32(&sigIndex))
         return d.fail("expected signature index");
 
     if (sigIndex >= init.sigs.length())
         return d.fail("signature index out of range");
@@ -1166,17 +1076,17 @@ wasm::Compile(const ShareableBytes& byte
 
     auto init = js::MakeUnique<ModuleGeneratorData>();
     if (!init)
         return nullptr;
 
     if (!DecodePreamble(d))
         return nullptr;
 
-    if (!DecodeTypeSection(d, init.get()))
+    if (!DecodeTypeSection(d, &init->sigs))
         return nullptr;
 
     ImportVector imports;
     if (!DecodeImportSection(d, init.get(), &imports))
         return nullptr;
 
     if (!DecodeFunctionSection(d, init.get()))
         return nullptr;