diff --git a/js/src/asmjs/AsmJS.cpp b/js/src/asmjs/AsmJS.cpp index 532157c87803..47608f8985d2 100644 --- a/js/src/asmjs/AsmJS.cpp +++ b/js/src/asmjs/AsmJS.cpp @@ -7578,8 +7578,6 @@ ValidateGlobalVariable(JSContext* cx, const AsmJSGlobal& global, HandleValue imp *val = Val(simdConstant.asInt32x4()); return true; } - case ValType::Limit: - MOZ_CRASH("Limit"); } } } diff --git a/js/src/asmjs/WasmAST.h b/js/src/asmjs/WasmAST.h index 3bc925869cf2..502dd8b67f7e 100644 --- a/js/src/asmjs/WasmAST.h +++ b/js/src/asmjs/WasmAST.h @@ -600,7 +600,7 @@ class AstGlobal : public AstNode Maybe init_; public: - AstGlobal() : isMutable_(false), type_(ValType::Limit) + AstGlobal() : isMutable_(false), type_(ValType(TypeCode::Limit)) {} explicit AstGlobal(AstName name, ValType type, bool isMutable, diff --git a/js/src/asmjs/WasmBinary.h b/js/src/asmjs/WasmBinary.h index 8390482bdbd4..e50f6d8ea007 100644 --- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -87,36 +87,58 @@ enum class SectionId { static const char NameSectionName[] = "name"; -enum class ValType +enum class TypeCode { - I32 = 0x01, - I64 = 0x02, - F32 = 0x03, - F64 = 0x04, + I32 = 0x7f, // SLEB128(-0x01) + I64 = 0x7e, // SLEB128(-0x02) + F32 = 0x7d, // SLEB128(-0x03) + F64 = 0x7c, // SLEB128(-0x04) + + // Only emitted internally for asm.js, likely to get collapsed into I128 + I8x16 = 0x7b, + I16x8 = 0x7a, + I32x4 = 0x79, + F32x4 = 0x78, + B8x16 = 0x77, + B16x8 = 0x76, + B32x4 = 0x75, + + // A function pointer with any signature + AnyFunc = 0x70, // SLEB128(-0x10) + + // Type constructor for function types + Func = 0x60, // SLEB128(-0x20) + + // Special code representing the block signature ()->() + BlockVoid = 0x40, // SLEB128(-0x40) + + // Type codes currently always fit in a single byte + Max = 0x7f, + Limit = 0x80 +}; + +enum class ValType : uint32_t // fix type so we can cast from any u8 in decoder +{ + I32 = uint8_t(TypeCode::I32), + I64 = uint8_t(TypeCode::I64), + F32 = uint8_t(TypeCode::F32), + F64 = uint8_t(TypeCode::F64), // ------------------------------------------------------------------------ // The rest of these types are currently only emitted internally when // compiling asm.js and are rejected by wasm validation. - I8x16, - I16x8, - I32x4, - F32x4, - B8x16, - B16x8, - B32x4, - - Limit + I8x16 = uint8_t(TypeCode::I8x16), + I16x8 = uint8_t(TypeCode::I16x8), + I32x4 = uint8_t(TypeCode::I32x4), + F32x4 = uint8_t(TypeCode::F32x4), + B8x16 = uint8_t(TypeCode::B8x16), + B16x8 = uint8_t(TypeCode::B16x8), + B32x4 = uint8_t(TypeCode::B32x4) }; typedef Vector ValTypeVector; -enum class TypeConstructor -{ - AnyFunc = 0x20, - Function = 0x40 -}; - enum class DefinitionKind { Function = 0x00, @@ -131,7 +153,7 @@ enum class GlobalFlags AllowedMask = 0x1 }; -enum class Expr +enum class Expr : uint32_t // fix type so we can cast from any u16 in decoder { // Control flow operators Unreachable = 0x00, @@ -456,22 +478,24 @@ enum class Expr // generalized to a list of ValType and this enum will go away, replaced, // wherever it is used, by a varU32 + list of ValType. -enum class ExprType +enum class ExprType : uint32_t // fix type so we can cast from any u8 in decoder { - Void = 0x00, - I32 = uint8_t(ValType::I32), - I64 = uint8_t(ValType::I64), - F32 = uint8_t(ValType::F32), - F64 = uint8_t(ValType::F64), - I8x16 = uint8_t(ValType::I8x16), - I16x8 = uint8_t(ValType::I16x8), - I32x4 = uint8_t(ValType::I32x4), - F32x4 = uint8_t(ValType::F32x4), - B8x16 = uint8_t(ValType::B8x16), - B16x8 = uint8_t(ValType::B16x8), - B32x4 = uint8_t(ValType::B32x4), + Void = uint8_t(TypeCode::BlockVoid), - Limit + I32 = uint8_t(TypeCode::I32), + I64 = uint8_t(TypeCode::I64), + F32 = uint8_t(TypeCode::F32), + F64 = uint8_t(TypeCode::F64), + + I8x16 = uint8_t(TypeCode::I8x16), + I16x8 = uint8_t(TypeCode::I16x8), + I32x4 = uint8_t(TypeCode::I32x4), + F32x4 = uint8_t(TypeCode::F32x4), + B8x16 = uint8_t(TypeCode::B8x16), + B16x8 = uint8_t(TypeCode::B16x8), + B32x4 = uint8_t(TypeCode::B32x4), + + Limit = uint8_t(TypeCode::Limit) }; typedef int8_t I8x16[16]; @@ -613,12 +637,14 @@ class Encoder return writeVarS(i); } MOZ_MUST_USE bool writeValType(ValType type) { - static_assert(size_t(ValType::Limit) <= INT8_MAX, "fits"); - return writeFixedU8(size_t(type)); + static_assert(size_t(TypeCode::Max) <= INT8_MAX, "fits"); + MOZ_ASSERT(size_t(type) <= size_t(TypeCode::Max)); + return writeFixedU8(uint8_t(type)); } - MOZ_MUST_USE bool writeExprType(ExprType type) { - static_assert(size_t(ExprType::Limit) <= INT8_MAX, "fits"); - return writeFixedU8(size_t(type)); + MOZ_MUST_USE bool writeBlockType(ExprType type) { + static_assert(size_t(TypeCode::Max) <= INT8_MAX, "fits"); + MOZ_ASSERT(size_t(type) <= size_t(TypeCode::Max)); + return writeFixedU8(uint8_t(type)); } MOZ_MUST_USE bool writeExpr(Expr expr) { static_assert(size_t(Expr::Limit) <= ExprLimit, "fits"); @@ -857,13 +883,21 @@ class Decoder return readVarS(out); } MOZ_MUST_USE bool readValType(ValType* type) { - static_assert(uint8_t(ValType::Limit) <= INT8_MAX, "fits"); + static_assert(uint8_t(TypeCode::Max) <= INT8_MAX, "fits"); uint8_t u8; if (!readFixedU8(&u8)) return false; *type = (ValType)u8; return true; } + MOZ_MUST_USE bool readBlockType(ExprType* type) { + static_assert(size_t(TypeCode::Max) <= INT8_MAX, "fits"); + uint8_t u8; + if (!readFixedU8(&u8)) + return false; + *type = (ExprType)u8; + return true; + } MOZ_MUST_USE bool readExpr(Expr* expr) { static_assert(size_t(Expr::Limit) <= ExprLimit, "fits"); uint8_t u8; @@ -877,7 +911,7 @@ class Decoder return false; if (u8 == UINT8_MAX) return false; - *expr = Expr(u8 + UINT8_MAX); + *expr = Expr(uint16_t(u8) + UINT8_MAX); return true; } diff --git a/js/src/asmjs/WasmBinaryFormat.cpp b/js/src/asmjs/WasmBinaryFormat.cpp index 35888d61e90b..550d1fe7a9cb 100644 --- a/js/src/asmjs/WasmBinaryFormat.cpp +++ b/js/src/asmjs/WasmBinaryFormat.cpp @@ -41,7 +41,7 @@ bool wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals) { uint32_t numLocalEntries = 0; - ValType prev = ValType::Limit; + ValType prev = ValType(TypeCode::Limit); for (ValType t : locals) { if (t != prev) { numLocalEntries++; diff --git a/js/src/asmjs/WasmBinaryIterator.h b/js/src/asmjs/WasmBinaryIterator.h index ae244044225c..24e22325937a 100644 --- a/js/src/asmjs/WasmBinaryIterator.h +++ b/js/src/asmjs/WasmBinaryIterator.h @@ -192,7 +192,7 @@ class TypeAndValue Value value_; public: - TypeAndValue() : type_(ValType::Limit), value_() {} + TypeAndValue() : type_(ValType(TypeCode::Limit)), value_() {} explicit TypeAndValue(ValType type) : type_(type), value_() {} @@ -217,7 +217,7 @@ class TypeAndValue ValType type_; public: - TypeAndValue() : type_(ValType::Limit) {} + TypeAndValue() : type_(ValType(TypeCode::Limit)) {} explicit TypeAndValue(ValType type) : type_(type) {} TypeAndValue(ValType type, Nothing value) @@ -375,7 +375,7 @@ class MOZ_STACK_CLASS ExprIter : private Policy } MOZ_MUST_USE bool readLinearMemoryAddress(uint32_t byteSize, LinearMemoryAddress* addr); - MOZ_MUST_USE bool readExprType(ExprType* expr); + MOZ_MUST_USE bool readBlockType(ExprType* expr); MOZ_MUST_USE bool typeMismatch(ExprType actual, ExprType expected) MOZ_COLD; MOZ_MUST_USE bool checkType(ValType actual, ValType expected); @@ -809,16 +809,30 @@ ExprIter::popControl(LabelKind* kind, ExprType* type, Value* value) template inline bool -ExprIter::readExprType(ExprType* type) +ExprIter::readBlockType(ExprType* type) { - uint8_t byte; - if (!readFixedU8(&byte)) + if (!d_.readBlockType(type)) return fail("unable to read block signature"); - if (Validate && byte >= uint8_t(ExprType::Limit)) - return fail("invalid inline type"); - - *type = ExprType(byte); + if (Validate) { + switch (*type) { + case ExprType::Void: + case ExprType::I32: + case ExprType::I64: + case ExprType::F32: + case ExprType::F64: + case ExprType::I8x16: + case ExprType::I16x8: + case ExprType::I32x4: + case ExprType::F32x4: + case ExprType::B8x16: + case ExprType::B16x8: + case ExprType::B32x4: + break; + default: + return fail("invalid inline block type"); + } + } return true; } @@ -898,7 +912,7 @@ ExprIter::readBlock() MOZ_ASSERT(Classify(expr_) == ExprKind::Block); ExprType type = ExprType::Limit; - if (!readExprType(&type)) + if (!readBlockType(&type)) return false; return pushControl(LabelKind::Block, type, false); @@ -911,7 +925,7 @@ ExprIter::readLoop() MOZ_ASSERT(Classify(expr_) == ExprKind::Loop); ExprType type = ExprType::Limit; - if (!readExprType(&type)) + if (!readBlockType(&type)) return false; return pushControl(LabelKind::Loop, type, reachable_); @@ -924,7 +938,7 @@ ExprIter::readIf(Value* condition) MOZ_ASSERT(Classify(expr_) == ExprKind::If); ExprType type = ExprType::Limit; - if (!readExprType(&type)) + if (!readBlockType(&type)) return false; if (MOZ_LIKELY(reachable_)) { diff --git a/js/src/asmjs/WasmBinaryToAST.cpp b/js/src/asmjs/WasmBinaryToAST.cpp index 699f262cd341..6673db66ffe5 100644 --- a/js/src/asmjs/WasmBinaryToAST.cpp +++ b/js/src/asmjs/WasmBinaryToAST.cpp @@ -1472,7 +1472,7 @@ AstDecodeTypeSection(AstDecodeContext& c) for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) { uint32_t form; - if (!c.d.readVarU32(&form) || form != uint32_t(TypeConstructor::Function)) + if (!c.d.readVarU32(&form) || form != uint32_t(TypeCode::Func)) return c.d.fail("expected function form"); uint32_t numArgs; @@ -1586,7 +1586,7 @@ AstDecodeTableSection(AstDecodeContext& c) if (!c.d.readVarU32(&typeConstructorValue)) return c.d.fail("expected type constructor kind"); - if (typeConstructorValue != uint32_t(TypeConstructor::AnyFunc)) + if (typeConstructorValue != uint32_t(TypeCode::AnyFunc)) return c.d.fail("unknown type constructor kind"); Limits table; @@ -1631,7 +1631,7 @@ AstDecodeLimitsTable(AstDecodeContext& c, Limits* limits) if (!c.d.readVarU32(&kind)) return false; - if (kind != uint32_t(TypeConstructor::AnyFunc)) + if (kind != uint32_t(TypeCode::AnyFunc)) return c.d.fail("unknown type constructor kind"); if (!DecodeLimits(c.d, limits)) diff --git a/js/src/asmjs/WasmCompile.cpp b/js/src/asmjs/WasmCompile.cpp index de87ff0677ce..4ffb79d20c74 100644 --- a/js/src/asmjs/WasmCompile.cpp +++ b/js/src/asmjs/WasmCompile.cpp @@ -147,42 +147,6 @@ DecodeCallIndirect(FunctionDecoder& f) return DecodeCallReturn(f, sig); } -static bool -DecodeBlock(FunctionDecoder& f) -{ - if (!f.iter().readBlock()) - return false; - - if (f.iter().controlType() > ExprType::F64) - return f.iter().fail("unknown block signature type"); - - return true; -} - -static bool -DecodeLoop(FunctionDecoder& f) -{ - if (!f.iter().readLoop()) - return false; - - if (f.iter().controlType() > ExprType::F64) - return f.iter().fail("unknown loop signature type"); - - return true; -} - -static bool -DecodeIf(FunctionDecoder& f) -{ - if (!f.iter().readIf(nullptr)) - return false; - - if (f.iter().controlType() > ExprType::F64) - return f.iter().fail("unknown if signature type"); - - return true; -} - static bool DecodeBrTable(FunctionDecoder& f) { @@ -247,11 +211,11 @@ DecodeFunctionBodyExprs(FunctionDecoder& f) case Expr::Select: CHECK(f.iter().readSelect(nullptr, nullptr, nullptr, nullptr)); case Expr::Block: - CHECK(DecodeBlock(f)); + CHECK(f.iter().readBlock()); case Expr::Loop: - CHECK(DecodeLoop(f)); + CHECK(f.iter().readLoop()); case Expr::If: - CHECK(DecodeIf(f)); + CHECK(f.iter().readIf(nullptr)); case Expr::Else: CHECK(f.iter().readElse(nullptr, nullptr)); case Expr::I32Clz: @@ -488,7 +452,7 @@ DecodeTypeSection(Decoder& d, ModuleGeneratorData* init) for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) { uint32_t form; - if (!d.readVarU32(&form) || form != uint32_t(TypeConstructor::Function)) + if (!d.readVarU32(&form) || form != uint32_t(TypeCode::Func)) return d.fail("expected function form"); uint32_t numArgs; @@ -642,7 +606,7 @@ DecodeResizableTable(Decoder& d, ModuleGeneratorData* init) if (!d.readVarU32(&elementType)) return d.fail("expected table element type"); - if (elementType != uint32_t(TypeConstructor::AnyFunc)) + if (elementType != uint32_t(TypeCode::AnyFunc)) return d.fail("expected 'anyfunc' element type"); Limits limits; diff --git a/js/src/asmjs/WasmGenerator.cpp b/js/src/asmjs/WasmGenerator.cpp index ba342f269939..0fa982c5fc56 100644 --- a/js/src/asmjs/WasmGenerator.cpp +++ b/js/src/asmjs/WasmGenerator.cpp @@ -670,9 +670,6 @@ ModuleGenerator::allocateGlobal(GlobalDesc* global) case ValType::B32x4: width = 16; break; - case ValType::Limit: - MOZ_CRASH("Limit"); - break; } uint32_t offset; diff --git a/js/src/asmjs/WasmInstance.cpp b/js/src/asmjs/WasmInstance.cpp index 454f3f476ac7..7193660dc218 100644 --- a/js/src/asmjs/WasmInstance.cpp +++ b/js/src/asmjs/WasmInstance.cpp @@ -166,7 +166,6 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con case ValType::B8x16: case ValType::B16x8: case ValType::B32x4: - case ValType::Limit: MOZ_CRASH("unhandled type in callImport"); } } @@ -239,7 +238,6 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con case ValType::B8x16: MOZ_CRASH("NYI"); case ValType::B16x8: MOZ_CRASH("NYI"); case ValType::B32x4: MOZ_CRASH("NYI"); - case ValType::Limit: MOZ_CRASH("Limit"); } if (!TypeScript::ArgTypes(script, i)->hasType(type)) return true; @@ -640,8 +638,6 @@ Instance::callExport(JSContext* cx, uint32_t funcDefIndex, CallArgs args) memcpy(&exportArgs[i], simd.asInt32x4(), Simd128DataSize); break; } - case ValType::Limit: - MOZ_CRASH("Limit"); } } diff --git a/js/src/asmjs/WasmIonCompile.cpp b/js/src/asmjs/WasmIonCompile.cpp index 29a59db8eee0..2e656a09a41a 100644 --- a/js/src/asmjs/WasmIonCompile.cpp +++ b/js/src/asmjs/WasmIonCompile.cpp @@ -264,8 +264,6 @@ class FunctionCompiler // Bool32x4 uses the same data layout as Int32x4. ins = MSimdConstant::New(alloc(), SimdConstant::SplatX4(0), MIRType::Bool32x4); break; - case ValType::Limit: - MOZ_CRASH("Limit"); } curBlock_->add(ins); @@ -2685,7 +2683,7 @@ SimdToLaneType(ValType type) case ValType::I64: case ValType::F32: case ValType::F64: - case ValType::Limit:; + break; } MOZ_CRASH("bad simd type"); } @@ -2971,7 +2969,6 @@ EmitSimdCtor(FunctionCompiler& f, ValType type) case ValType::I64: case ValType::F32: case ValType::F64: - case ValType::Limit: break; } MOZ_CRASH("unexpected SIMD type"); diff --git a/js/src/asmjs/WasmTextToBinary.cpp b/js/src/asmjs/WasmTextToBinary.cpp index 8255f55bdfb4..3e197fd31642 100644 --- a/js/src/asmjs/WasmTextToBinary.cpp +++ b/js/src/asmjs/WasmTextToBinary.cpp @@ -3859,7 +3859,7 @@ EncodeBlock(Encoder& e, AstBlock& b) if (!e.writeExpr(b.expr())) return false; - if (!e.writeExprType(b.type())) + if (!e.writeBlockType(b.type())) return false; if (!EncodeExprList(e, b.exprs())) @@ -4063,7 +4063,7 @@ EncodeIf(Encoder& e, AstIf& i) if (!EncodeExpr(e, i.cond()) || !e.writeExpr(Expr::If)) return false; - if (!e.writeExprType(i.type())) + if (!e.writeBlockType(i.type())) return false; if (!EncodeExprList(e, i.thenExprs())) @@ -4228,7 +4228,7 @@ EncodeTypeSection(Encoder& e, AstModule& module) return false; for (AstSig* sig : module.sigs()) { - if (!e.writeVarU32(uint32_t(TypeConstructor::Function))) + if (!e.writeVarU32(uint32_t(TypeCode::Func))) return false; if (!e.writeVarU32(sig->args().length())) @@ -4303,7 +4303,7 @@ EncodeLimits(Encoder& e, const Limits& limits) static bool EncodeTableLimits(Encoder& e, const Limits& limits) { - if (!e.writeVarU32(uint32_t(TypeConstructor::AnyFunc))) + if (!e.writeVarU32(uint32_t(TypeCode::AnyFunc))) return false; return EncodeLimits(e, limits); diff --git a/js/src/asmjs/WasmTypes.cpp b/js/src/asmjs/WasmTypes.cpp index 74383831862b..bd5529aec04a 100644 --- a/js/src/asmjs/WasmTypes.cpp +++ b/js/src/asmjs/WasmTypes.cpp @@ -62,8 +62,6 @@ Val::writePayload(uint8_t* dst) const case ValType::B32x4: memcpy(dst, &u, jit::Simd128DataSize); return; - case ValType::Limit: - MOZ_CRASH("Bad value type"); } } diff --git a/js/src/asmjs/WasmTypes.h b/js/src/asmjs/WasmTypes.h index b83aeb9c0d43..7629fe2ffe4b 100644 --- a/js/src/asmjs/WasmTypes.h +++ b/js/src/asmjs/WasmTypes.h @@ -269,7 +269,6 @@ ToMIRType(ValType vt) case ValType::B8x16: return jit::MIRType::Bool8x16; case ValType::B16x8: return jit::MIRType::Bool16x8; case ValType::B32x4: return jit::MIRType::Bool32x4; - case ValType::Limit: break; } MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type"); } diff --git a/js/src/jit-test/lib/wasm-binary.js b/js/src/jit-test/lib/wasm-binary.js index 8ca03e08f3e7..705a45599d20 100644 --- a/js/src/jit-test/lib/wasm-binary.js +++ b/js/src/jit-test/lib/wasm-binary.js @@ -11,32 +11,30 @@ const ver2 = (Wasm.experimentalVersion >>> 16) & 0xff; const ver3 = (Wasm.experimentalVersion >>> 24) & 0xff; // Section opcodes -const userDefinedId = 0; -const typeId = 1; -const importId = 2; -const functionId = 3; -const tableId = 4; -const memoryId = 5; -const globalId = 6; -const exportId = 7; -const startId = 8; -const elemId = 9; -const codeId = 10; -const dataId = 11; +const userDefinedId = 0; +const typeId = 1; +const importId = 2; +const functionId = 3; +const tableId = 4; +const memoryId = 5; +const globalId = 6; +const exportId = 7; +const startId = 8; +const elemId = 9; +const codeId = 10; +const dataId = 11; // User-defined section names -const nameName = "name"; +const nameName = "name"; // Type codes -const VoidCode = 0; -const I32Code = 1; -const I64Code = 2; -const F32Code = 3; -const F64Code = 4; - -// Type constructors -const AnyFuncCode = 0x20; -const FunctionConstructorCode = 0x40; +const I32Code = 0x7f; +const I64Code = 0x7e; +const F32Code = 0x7d; +const F64Code = 0x7c; +const AnyFuncCode = 0x70; +const FuncCode = 0x60; +const VoidCode = 0x40; // Opcodes const UnreachableCode = 0x00; @@ -86,11 +84,11 @@ const I64TruncUF64Code = 0xa5; const GrowMemoryCode = 0x39; // DefinitionKind -const FunctionCode = 0x00; -const TableCode = 0x01; -const MemoryCode = 0x02; -const GlobalCode = 0x03; +const FunctionCode = 0x00; +const TableCode = 0x01; +const MemoryCode = 0x02; +const GlobalCode = 0x03; // ResizableFlags -const HasMaximumFlag = 0x1; +const HasMaximumFlag = 0x1; diff --git a/js/src/jit-test/tests/wasm/binary.js b/js/src/jit-test/tests/wasm/binary.js index 7c03fadb7ca9..37942d2c65df 100644 --- a/js/src/jit-test/tests/wasm/binary.js +++ b/js/src/jit-test/tests/wasm/binary.js @@ -129,7 +129,7 @@ function sigSection(sigs) { var body = []; body.push(...varU32(sigs.length)); for (let sig of sigs) { - body.push(...varU32(FunctionConstructorCode)); + body.push(...varU32(FuncCode)); body.push(...varU32(sig.args.length)); for (let arg of sig.args) body.push(...varU32(arg)); @@ -245,7 +245,7 @@ const v2vBody = funcBody({locals:[], body:[]}); assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: U32MAX_LEB } ])), CompileError, /too many signatures/); assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), CompileError, /expected function form/); -assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FunctionConstructorCode, ...U32MAX_LEB], } ])), CompileError, /too many arguments in signature/); +assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FuncCode, ...U32MAX_LEB], } ])), CompileError, /too many arguments in signature/); assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1]}])), CompileError); assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1, 1, 0]}])), CompileError); @@ -346,7 +346,8 @@ wasmEval(moduleWithSections([userDefSec, userDefSec, sigSec, declSec, bodySec])) wasmEval(moduleWithSections([userDefSec, userDefSec, sigSec, userDefSec, declSec, userDefSec, bodySec])); // Diagnose nonstandard block signature types. -assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[BlockCode, F64Code + 1, EndCode]})])])), CompileError, /unknown block signature type/); +for (var bad of [0xff, 0, 1, 0x3f]) + assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[BlockCode, bad, EndCode]})])])), CompileError, /invalid inline block type/); // Checking stack trace. function runStackTraceTest(namesContent, expectedName) {