Bug 1316635: Factor out DecodeTypeSection; r?luke
MozReview-Commit-ID: HOaUFi8npPN
--- 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, §ionStart, §ionSize, "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, §ionStart, §ionSize, "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, §ionStart, §ionSize, "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;