diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-01-08 17:43:25 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-08 17:43:25 -0800 |
commit | 77329439d6307d292e59986db3a194c3085abbe2 (patch) | |
tree | ac9f4ad3787f2e0d3644d34ff324a546380a17fd /src | |
parent | 8d4db9fb86c3b80df3eaa0d8e5eb379d081c8399 (diff) | |
download | binaryen-77329439d6307d292e59986db3a194c3085abbe2.tar.gz binaryen-77329439d6307d292e59986db3a194c3085abbe2.tar.bz2 binaryen-77329439d6307d292e59986db3a194c3085abbe2.zip |
Remove implicit conversion operators from Type (#2577)
* Remove implicit conversion operators from Type
Now types must be explicitly converted to uint32_t with Type::getID or
to ValueType with Type::getVT. This fixes #2572 for switches that use
Type::getVT.
* getVT => getSingle
Diffstat (limited to 'src')
30 files changed, 217 insertions, 208 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 1f1805379..fb9635018 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1508,7 +1508,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { assert(params[i] == Type::f64 || curr->operands[i]->type == Type::unreachable); // overloaded, upgrade to f64 - switch (curr->operands[i]->type) { + switch (curr->operands[i]->type.getSingle()) { case Type::i32: curr->operands[i] = parent->builder.makeUnary( ConvertSInt32ToFloat64, curr->operands[i]); @@ -1529,7 +1529,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { if (importResults == Type::f64) { // we use a JS f64 value which is the most general, and convert to // it - switch (old) { + switch (old.getSingle()) { case Type::i32: { Unary* trunc = parent->builder.makeUnary(TruncSFloat64ToInt32, curr); diff --git a/src/asmjs/asm_v_wasm.cpp b/src/asmjs/asm_v_wasm.cpp index b499bd6e2..2f86370c1 100644 --- a/src/asmjs/asm_v_wasm.cpp +++ b/src/asmjs/asm_v_wasm.cpp @@ -42,7 +42,7 @@ Type asmToWasmType(AsmType asmType) { } AsmType wasmToAsmType(Type type) { - switch (type) { + switch (type.getSingle()) { case Type::i32: return ASM_INT; case Type::f32: @@ -67,7 +67,7 @@ AsmType wasmToAsmType(Type type) { } char getSig(Type type) { - switch (type) { + switch (type.getSingle()) { case Type::i32: return 'i'; case Type::i64: diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 44830cd75..79571bd96 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -50,8 +50,8 @@ static_assert(sizeof(BinaryenLiteral) == sizeof(Literal), BinaryenLiteral toBinaryenLiteral(Literal x) { BinaryenLiteral ret; - ret.type = x.type; - switch (x.type) { + ret.type = x.type.getID(); + switch (x.type.getSingle()) { case Type::i32: ret.i32 = x.geti32(); break; @@ -305,11 +305,11 @@ BinaryenType BinaryenTypeCreate(BinaryenType* types, uint32_t numTypes) { } std::cout << "};\n"; std::cout << " BinaryenTypeCreate(" << array << ", " << numTypes - << "); // " << uint32_t(result) << "\n"; + << "); // " << result.getID() << "\n"; std::cout << " }\n"; } - return uint32_t(result); + return result.getID(); } uint32_t BinaryenTypeArity(BinaryenType t) { return Type(t).size(); } @@ -317,7 +317,7 @@ uint32_t BinaryenTypeArity(BinaryenType t) { return Type(t).size(); } void BinaryenTypeExpand(BinaryenType t, BinaryenType* buf) { const std::vector<Type>& types = Type(t).expand(); for (size_t i = 0; i < types.size(); ++i) { - buf[i] = types[i]; + buf[i] = types[i].getSingle(); } } @@ -1833,7 +1833,7 @@ BinaryenType BinaryenExpressionGetType(BinaryenExpressionRef expr) { << "]);\n"; } - return ((Expression*)expr)->type; + return ((Expression*)expr)->type.getID(); } void BinaryenExpressionPrint(BinaryenExpressionRef expr) { if (tracing) { @@ -2643,7 +2643,7 @@ BinaryenType BinaryenAtomicWaitGetExpectedType(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<AtomicWait>()); - return static_cast<AtomicWait*>(expression)->expectedType; + return static_cast<AtomicWait*>(expression)->expectedType.getID(); } // AtomicNotify BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr) { @@ -4112,7 +4112,7 @@ BinaryenType BinaryenFunctionGetParams(BinaryenFunctionRef func) { << "]);\n"; } - return ((Function*)func)->sig.params; + return ((Function*)func)->sig.params.getID(); } BinaryenType BinaryenFunctionGetResults(BinaryenFunctionRef func) { if (tracing) { @@ -4120,7 +4120,7 @@ BinaryenType BinaryenFunctionGetResults(BinaryenFunctionRef func) { << "]);\n"; } - return ((Function*)func)->sig.results; + return ((Function*)func)->sig.results.getID(); } BinaryenIndex BinaryenFunctionGetNumVars(BinaryenFunctionRef func) { if (tracing) { @@ -4139,7 +4139,7 @@ BinaryenType BinaryenFunctionGetVar(BinaryenFunctionRef func, auto* fn = (Function*)func; assert(index < fn->vars.size()); - return fn->vars[index]; + return fn->vars[index].getID(); } BinaryenExpressionRef BinaryenFunctionGetBody(BinaryenFunctionRef func) { if (tracing) { @@ -4230,7 +4230,7 @@ BinaryenType BinaryenGlobalGetType(BinaryenGlobalRef global) { << "]);\n"; } - return ((Global*)global)->type; + return ((Global*)global)->type.getID(); } int BinaryenGlobalIsMutable(BinaryenGlobalRef global) { if (tracing) { @@ -4273,7 +4273,7 @@ BinaryenType BinaryenEventGetParams(BinaryenEventRef event) { std::cout << " BinaryenEventGetParams(events[" << events[event] << "]);\n"; } - return ((Event*)event)->sig.params; + return ((Event*)event)->sig.params.getID(); } BinaryenType BinaryenEventGetResults(BinaryenEventRef event) { @@ -4282,7 +4282,7 @@ BinaryenType BinaryenEventGetResults(BinaryenEventRef event) { << "]);\n"; } - return ((Event*)event)->sig.results; + return ((Event*)event)->sig.results.getID(); } // diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index a61af9ce5..fc9d74743 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -137,8 +137,8 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) { visitor.visitInt(curr->isReturn); } void visitCallIndirect(CallIndirect* curr) { - visitor.visitInt(curr->sig.params); - visitor.visitInt(curr->sig.results); + visitor.visitInt(curr->sig.params.getID()); + visitor.visitInt(curr->sig.results.getID()); visitor.visitInt(curr->isReturn); } void visitLocalGet(LocalGet* curr) { visitor.visitIndex(curr->index); } @@ -164,7 +164,7 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) { visitor.visitAddress(curr->offset); visitor.visitAddress(curr->align); visitor.visitInt(curr->isAtomic); - visitor.visitInt(curr->valueType); + visitor.visitInt(curr->valueType.getID()); } void visitAtomicRMW(AtomicRMW* curr) { visitor.visitInt(curr->op); @@ -438,7 +438,7 @@ HashType ExpressionAnalyzer::hash(Expression* curr) { // if we hash between modules, then we need to take int account // call_imports type, etc. The simplest thing is just to hash the // type for all of them. - hash(curr->type); + hash(curr->type.getID()); // Blocks and loops introduce scoping. if (auto* block = curr->dynCast<Block>()) { noteScopeName(block->name); @@ -477,7 +477,7 @@ HashType ExpressionAnalyzer::hash(Expression* curr) { void visitNonScopeName(Name curr) { return hash64(uint64_t(curr.str)); } void visitInt(int32_t curr) { hash(curr); } void visitLiteral(Literal curr) { hash(std::hash<Literal>()(curr)); } - void visitType(Type curr) { hash(int32_t(curr)); } + void visitType(Type curr) { hash(int32_t(curr.getSingle())); } void visitIndex(Index curr) { static_assert(sizeof(Index) == sizeof(int32_t), "wasm64 will need changes here"); diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 5e72850e6..422f462c0 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -181,7 +181,7 @@ void ReFinalize::replaceUntaken(Expression* value, Expression* condition) { condition = builder.makeDrop(condition); } replacement = builder.makeSequence(value, condition); - assert(replacement->type); + assert(replacement->type.getSingle()); } replaceCurrent(replacement); } diff --git a/src/ir/abstract.h b/src/ir/abstract.h index 06a1cd41c..f7bc664dd 100644 --- a/src/ir/abstract.h +++ b/src/ir/abstract.h @@ -52,7 +52,7 @@ enum Op { // you can provide i32 and Add and receive the specific opcode for a 32-bit // addition, AddInt32. If the op does not exist, it returns Invalid. inline UnaryOp getUnary(Type type, Op op) { - switch (type) { + switch (type.getSingle()) { case Type::i32: { return InvalidUnary; } @@ -93,7 +93,7 @@ inline UnaryOp getUnary(Type type, Op op) { } inline BinaryOp getBinary(Type type, Op op) { - switch (type) { + switch (type.getSingle()) { case Type::i32: { switch (op) { case Add: diff --git a/src/ir/hashed.h b/src/ir/hashed.h index 9e9717cda..fe0a0b958 100644 --- a/src/ir/hashed.h +++ b/src/ir/hashed.h @@ -82,10 +82,10 @@ struct FunctionHasher : public WalkerPass<PostWalker<FunctionHasher>> { static HashType hashFunction(Function* func) { HashType ret = 0; - ret = rehash(ret, (HashType)func->sig.params); - ret = rehash(ret, (HashType)func->sig.results); + ret = rehash(ret, (HashType)func->sig.params.getID()); + ret = rehash(ret, (HashType)func->sig.results.getID()); for (auto type : func->vars) { - ret = rehash(ret, (HashType)type); + ret = rehash(ret, (HashType)type.getSingle()); } ret = rehash(ret, (HashType)ExpressionAnalyzer::hash(func->body)); return ret; diff --git a/src/literal.h b/src/literal.h index ef3e13d44..bce578d46 100644 --- a/src/literal.h +++ b/src/literal.h @@ -65,7 +65,7 @@ public: bool isNone() { return type == Type::none; } static Literal makeFromInt32(int32_t x, Type type) { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(int32_t(x)); break; @@ -454,7 +454,7 @@ template<> struct hash<wasm::Literal> { a.getBits(bytes); int64_t chunks[2]; memcpy(chunks, bytes, sizeof(chunks)); - return wasm::rehash(wasm::rehash(uint64_t(hash<size_t>()(size_t(a.type))), + return wasm::rehash(wasm::rehash(uint64_t(hash<uint32_t>()(a.type.getID())), uint64_t(hash<int64_t>()(chunks[0]))), uint64_t(hash<int64_t>()(chunks[1]))); } @@ -464,10 +464,10 @@ template<> struct less<wasm::Literal> { if (a.type < b.type) { return true; } - if (a.type > b.type) { + if (b.type < a.type) { return false; } - switch (a.type) { + switch (a.type.getSingle()) { case wasm::Type::i32: return a.geti32() < b.geti32(); case wasm::Type::f32: diff --git a/src/parsing.h b/src/parsing.h index a75e953b4..7da5a22b0 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -84,7 +84,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { ret->type = type; if (type.isFloat()) { if (s == _INFINITY) { - switch (type) { + switch (type.getSingle()) { case Type::f32: ret->value = Literal(std::numeric_limits<float>::infinity()); break; @@ -98,7 +98,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { return ret; } if (s == NEG_INFINITY) { - switch (type) { + switch (type.getSingle()) { case Type::f32: ret->value = Literal(-std::numeric_limits<float>::infinity()); break; @@ -112,7 +112,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { return ret; } if (s == _NAN) { - switch (type) { + switch (type.getSingle()) { case Type::f32: ret->value = Literal(float(std::nan(""))); break; @@ -137,7 +137,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { if (!(modifier ? positive[4] == '0' && positive[5] == 'x' : 1)) { throw ParseException("bad nan input"); } - switch (type) { + switch (type.getSingle()) { case Type::f32: { uint32_t pattern; if (modifier) { @@ -187,7 +187,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { return ret; } if (s == NEG_NAN) { - switch (type) { + switch (type.getSingle()) { case Type::f32: ret->value = Literal(float(-std::nan(""))); break; @@ -201,7 +201,7 @@ parseConst(cashew::IString s, Type type, MixedArena& allocator) { return ret; } } - switch (type) { + switch (type.getSingle()) { case Type::i32: { if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp index 6c79c4215..43c8ccaa7 100644 --- a/src/passes/ConstHoisting.cpp +++ b/src/passes/ConstHoisting.cpp @@ -77,7 +77,7 @@ private: } // measure the size of the constant Index size = 0; - switch (value.type) { + switch (value.type.getSingle()) { case Type::i32: { size = getWrittenSize(S32LEB(value.geti32())); break; diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp index 09c87c212..1fdf97c7b 100644 --- a/src/passes/FuncCastEmulation.cpp +++ b/src/passes/FuncCastEmulation.cpp @@ -44,7 +44,7 @@ static const int NUM_PARAMS = 16; // Converts a value to the ABI type of i64. static Expression* toABI(Expression* value, Module* module) { Builder builder(*module); - switch (value->type) { + switch (value->type.getSingle()) { case Type::i32: { value = builder.makeUnary(ExtendUInt32, value); break; @@ -88,7 +88,7 @@ static Expression* toABI(Expression* value, Module* module) { // Converts a value from the ABI type of i64 to the expected type static Expression* fromABI(Expression* value, Type type, Module* module) { Builder builder(*module); - switch (type) { + switch (type.getSingle()) { case Type::i32: { value = builder.makeUnary(WrapInt64, value); break; diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index c3ed6fb04..2072f6614 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -84,7 +84,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { private: void freeIdx() { - auto& freeList = pass.freeTemps[(int)ty]; + auto& freeList = pass.freeTemps[ty.getSingle()]; assert(std::find(freeList.begin(), freeList.end(), idx) == freeList.end()); freeList.push_back(idx); @@ -1459,7 +1459,7 @@ private: TempVar getTemp(Type ty = Type::i32) { Index ret; - auto& freeList = freeTemps[(int)ty]; + auto& freeList = freeTemps[ty.getSingle()]; if (freeList.size() > 0) { ret = freeList.back(); freeList.pop_back(); diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp index 3e3be6244..256ade4bc 100644 --- a/src/passes/InstrumentLocals.cpp +++ b/src/passes/InstrumentLocals.cpp @@ -74,7 +74,7 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { void visitLocalGet(LocalGet* curr) { Builder builder(*getModule()); Name import; - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: import = get_i32; break; @@ -122,7 +122,7 @@ struct InstrumentLocals : public WalkerPass<PostWalker<InstrumentLocals>> { Builder builder(*getModule()); Name import; - switch (curr->value->type) { + switch (curr->value->type.getSingle()) { case Type::i32: import = set_i32; break; diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp index 54f763734..4db409c10 100644 --- a/src/passes/InstrumentMemory.cpp +++ b/src/passes/InstrumentMemory.cpp @@ -86,7 +86,7 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> { curr->ptr}, Type::i32); Name target; - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: target = load_val_i32; break; @@ -117,7 +117,7 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> { curr->ptr}, Type::i32); Name target; - switch (curr->value->type) { + switch (curr->value->type.getSingle()) { case Type::i32: target = store_val_i32; break; diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 2372df462..ef7c17000 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -53,7 +53,7 @@ Name ANY_EXPR = "any.expr"; template<typename LocalInfoProvider> Index getMaxBits(Expression* curr, LocalInfoProvider* localInfoProvider) { if (auto* const_ = curr->dynCast<Const>()) { - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: return 32 - const_->value.countLeadingZeroes().geti32(); case Type::i64: @@ -178,7 +178,7 @@ Index getMaxBits(Expression* curr, LocalInfoProvider* localInfoProvider) { return 8 * load->bytes; } } - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: return 32; case Type::i64: @@ -260,7 +260,7 @@ struct LocalScanner : PostWalker<LocalScanner> { Index getMaxBitsForLocal(LocalGet* get) { return getBitsForType(get->type); } Index getBitsForType(Type type) { - switch (type) { + switch (type.getSingle()) { case Type::i32: return 32; case Type::i64: diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp index d758440f2..1866877c0 100644 --- a/src/passes/RemoveNonJSOps.cpp +++ b/src/passes/RemoveNonJSOps.cpp @@ -157,7 +157,7 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> { // Switch unaligned loads of floats to unaligned loads of integers (which we // can actually implement) and then use reinterpretation to get the float // back out. - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::f32: curr->type = Type::i32; replaceCurrent(builder->makeUnary(ReinterpretInt32, curr)); @@ -179,7 +179,7 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> { // Switch unaligned stores of floats to unaligned stores of integers (which // we can actually implement) and then use reinterpretation to store the // right value. - switch (curr->valueType) { + switch (curr->valueType.getSingle()) { case Type::f32: curr->valueType = Type::i32; curr->value = builder->makeUnary(ReinterpretFloat32, curr->value); diff --git a/src/shell-interface.h b/src/shell-interface.h index cd5e5210b..f1b68ab60 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -99,7 +99,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { // add spectest globals ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) { if (import->module == SPECTEST && import->base.startsWith(GLOBAL)) { - switch (import->type) { + switch (import->type.getSingle()) { case Type::i32: globals[import->name] = Literal(int32_t(666)); break; diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 81bd87581..e21c6a14d 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -312,7 +312,7 @@ private: SmallVector<Type, 2> getSubTypes(Type type) { SmallVector<Type, 2> ret; ret.push_back(type); // includes itself - switch (type) { + switch (type.getSingle()) { case Type::anyref: ret.push_back(Type::funcref); ret.push_back(Type::exnref); @@ -860,7 +860,7 @@ private: } nesting++; Expression* ret = nullptr; - switch (type) { + switch (type.getSingle()) { case Type::i32: case Type::i64: case Type::f32: @@ -1348,7 +1348,7 @@ private: Expression* makeNonAtomicLoad(Type type) { auto offset = logify(get()); auto ptr = makePointer(); - switch (type) { + switch (type.getSingle()) { case Type::i32: { bool signed_ = get() & 1; switch (upTo(3)) { @@ -1454,7 +1454,7 @@ private: auto offset = logify(get()); auto ptr = makePointer(); auto value = make(type); - switch (type) { + switch (type.getSingle()) { case Type::i32: { switch (upTo(3)) { case 0: @@ -1582,7 +1582,7 @@ private: switch (upTo(4)) { case 0: { // totally random, entire range - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(get32()); case Type::i64: @@ -1627,7 +1627,7 @@ private: default: WASM_UNREACHABLE("invalid value"); } - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(int32_t(small)); case Type::i64: @@ -1650,7 +1650,7 @@ private: case 2: { // special values Literal value; - switch (type) { + switch (type.getSingle()) { case Type::i32: value = Literal(pick<int32_t>(0, @@ -1725,7 +1725,7 @@ private: case 3: { // powers of 2 Literal value; - switch (type) { + switch (type.getSingle()) { case Type::i32: value = Literal(int32_t(1) << upTo(32)); break; @@ -1807,9 +1807,9 @@ private: return makeTrivial(type); } - switch (type) { + switch (type.getSingle()) { case Type::i32: { - switch (getConcreteType()) { + switch (getConcreteType().getSingle()) { case Type::i32: { auto op = pick( FeatureOptions<UnaryOp>() @@ -2026,7 +2026,7 @@ private: return makeTrivial(type); } - switch (type) { + switch (type.getSingle()) { case Type::i32: { switch (upTo(4)) { case 0: @@ -2331,7 +2331,7 @@ private: } } Index bytes; - switch (type) { + switch (type.getSingle()) { case Type::i32: { switch (upTo(3)) { case 0: @@ -2422,7 +2422,7 @@ private: Expression* makeSIMDExtract(Type type) { auto op = static_cast<SIMDExtractOp>(0); - switch (type) { + switch (type.getSingle()) { case Type::i32: op = pick(ExtractLaneSVecI8x16, ExtractLaneUVecI8x16, diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h index 2bad602f2..c6b6cc9c9 100644 --- a/src/tools/spec-wrapper.h +++ b/src/tools/spec-wrapper.h @@ -32,7 +32,7 @@ static std::string generateSpecWrapper(Module& wasm) { exp->name.str + "\" "; for (Type param : func->sig.params.expand()) { // zeros in arguments TODO more? - switch (param) { + switch (param.getSingle()) { case Type::i32: ret += "(i32.const 0)"; break; diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index 5a05fc7d2..ac00ce045 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -577,9 +577,9 @@ struct Reducer continue; // no conversion } Expression* fixed = nullptr; - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { - switch (child->type) { + switch (child->type.getSingle()) { case Type::i32: WASM_UNREACHABLE("invalid type"); case Type::i64: @@ -604,7 +604,7 @@ struct Reducer break; } case Type::i64: { - switch (child->type) { + switch (child->type.getSingle()) { case Type::i32: fixed = builder->makeUnary(ExtendSInt32, child); break; @@ -629,7 +629,7 @@ struct Reducer break; } case Type::f32: { - switch (child->type) { + switch (child->type.getSingle()) { case Type::i32: fixed = builder->makeUnary(ConvertSInt32ToFloat32, child); break; @@ -654,7 +654,7 @@ struct Reducer break; } case Type::f64: { - switch (child->type) { + switch (child->type.getSingle()) { case Type::i32: fixed = builder->makeUnary(ConvertSInt32ToFloat64, child); break; diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index fabcf5522..06ab81263 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -575,7 +575,7 @@ Ref AssertionEmitter::emitAssertReturnFunc(Builder& wasmBuilder, Expression* expected = sexpBuilder.parseExpression(e[2]); Type resType = expected->type; actual->type = resType; - switch (resType) { + switch (resType.getSingle()) { case Type::i32: body = wasmBuilder.makeBinary(EqInt32, actual, expected); break; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 6f8aa5744..b36f5c548 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -903,7 +903,7 @@ enum FeaturePrefix { inline S32LEB binaryType(Type type) { int ret = 0; - switch (type) { + switch (type.getSingle()) { // None only used for block signatures. TODO: Separate out? case Type::none: ret = BinaryConsts::EncodedType::Empty; diff --git a/src/wasm-builder.h b/src/wasm-builder.h index a625d7e54..cc31f5200 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -612,7 +612,7 @@ public: } Expression* makeConstExpression(Literal value) { - switch (value.type) { + switch (value.type.getSingle()) { case Type::nullref: return makeRefNull(); case Type::funcref: @@ -773,7 +773,7 @@ public: template<typename T> Expression* replaceWithIdenticalType(T* curr) { Literal value; // TODO: reuse node conditionally when possible for literals - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: value = Literal(int32_t(0)); break; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index a29af2216..cf5908adf 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1197,7 +1197,7 @@ public: // the default impls for load and store switch on the sizes. you can either // customize load/store, or the sub-functions which they call virtual Literal load(Load* load, Address addr) { - switch (load->type) { + switch (load->type.getSingle()) { case Type::i32: { switch (load->bytes) { case 1: @@ -1248,7 +1248,7 @@ public: WASM_UNREACHABLE("invalid type"); } virtual void store(Store* store, Address addr, Literal value) { - switch (store->valueType) { + switch (store->valueType.getSingle()) { case Type::i32: { switch (store->bytes) { case 1: diff --git a/src/wasm-type.h b/src/wasm-type.h index 18c429e95..0e3907af8 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -40,9 +40,13 @@ public: anyref, nullref, exnref, - _last_value_type, }; +private: + // Not in the enum because we don't want to have to have a case for it + static constexpr uint32_t last_value_type = exnref; + +public: Type() = default; // ValueType can be implicitly upgraded to Type @@ -60,14 +64,19 @@ public: const std::vector<Type>& expand() const; // Predicates - bool isSingle() const { return id >= i32 && id < _last_value_type; } - bool isMulti() const { return id >= _last_value_type; } - bool isConcrete() const { return id >= i32; } - bool isInteger() const { return id == i32 || id == i64; } - bool isFloat() const { return id == f32 || id == f64; } - bool isVector() const { return id == v128; }; - bool isNumber() const { return id >= i32 && id <= v128; } - bool isRef() const { return id >= funcref && id <= exnref; } + constexpr bool isSingle() const { return id >= i32 && id <= last_value_type; } + constexpr bool isMulti() const { return id > last_value_type; } + constexpr bool isConcrete() const { return id >= i32; } + constexpr bool isInteger() const { return id == i32 || id == i64; } + constexpr bool isFloat() const { return id == f32 || id == f64; } + constexpr bool isVector() const { return id == v128; }; + constexpr bool isNumber() const { return id >= i32 && id <= v128; } + constexpr bool isRef() const { return id >= funcref && id <= exnref; } + constexpr uint32_t getID() const { return id; } + constexpr ValueType getSingle() const { + assert(!isMulti() && "Unexpected multivalue type"); + return static_cast<ValueType>(id); + } // (In)equality must be defined for both Type and ValueType because it is // otherwise ambiguous whether to convert both this and other to int or @@ -80,9 +89,6 @@ public: // Order types by some notion of simplicity bool operator<(const Type& other) const; - // Allows for using Types in switch statements - constexpr operator uint32_t() const { return id; } - // Returns the type size in bytes. Only single types are supported. unsigned getByteSize() const; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 4f66b36e3..d5333847d 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -102,7 +102,7 @@ Literal Literal::castToI64() { } int64_t Literal::getInteger() const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return i32; case Type::i64: @@ -113,7 +113,7 @@ int64_t Literal::getInteger() const { } double Literal::getFloat() const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return getf32(); case Type::f64: @@ -125,7 +125,7 @@ double Literal::getFloat() const { void Literal::getBits(uint8_t (&buf)[16]) const { memset(buf, 0, 16); - switch (type) { + switch (type.getSingle()) { case Type::i32: case Type::f32: memcpy(buf, &i32, sizeof(i32)); @@ -266,7 +266,7 @@ void Literal::printVec128(std::ostream& o, const std::array<uint8_t, 16>& v) { std::ostream& operator<<(std::ostream& o, Literal literal) { prepareMinorColor(o); - switch (literal.type) { + switch (literal.type.getSingle()) { case Type::none: o << "?"; break; @@ -486,7 +486,7 @@ Literal Literal::truncSatToUI64() const { } Literal Literal::eqz() const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return eq(Literal(int32_t(0))); case Type::i64: @@ -508,7 +508,7 @@ Literal Literal::eqz() const { } Literal Literal::neg() const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(-uint32_t(i32)); case Type::i64: @@ -530,7 +530,7 @@ Literal Literal::neg() const { } Literal Literal::abs() const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 & 0x7fffffff); case Type::i64: @@ -552,7 +552,7 @@ Literal Literal::abs() const { } Literal Literal::ceil() const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(std::ceil(getf32())); case Type::f64: @@ -563,7 +563,7 @@ Literal Literal::ceil() const { } Literal Literal::floor() const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(std::floor(getf32())); case Type::f64: @@ -574,7 +574,7 @@ Literal Literal::floor() const { } Literal Literal::trunc() const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(std::trunc(getf32())); case Type::f64: @@ -585,7 +585,7 @@ Literal Literal::trunc() const { } Literal Literal::nearbyint() const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(std::nearbyint(getf32())); case Type::f64: @@ -596,7 +596,7 @@ Literal Literal::nearbyint() const { } Literal Literal::sqrt() const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(std::sqrt(getf32())); case Type::f64: @@ -635,7 +635,7 @@ Literal Literal::demote() const { } Literal Literal::add(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) + uint32_t(other.i32)); case Type::i64: @@ -657,7 +657,7 @@ Literal Literal::add(const Literal& other) const { } Literal Literal::sub(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) - uint32_t(other.i32)); case Type::i64: @@ -750,7 +750,7 @@ Literal Literal::subSatUI16(const Literal& other) const { } Literal Literal::mul(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) * uint32_t(other.i32)); case Type::i64: @@ -772,7 +772,7 @@ Literal Literal::mul(const Literal& other) const { } Literal Literal::div(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: { float lhs = getf32(), rhs = other.getf32(); float sign = std::signbit(lhs) == std::signbit(rhs) ? 0.f : -0.f; @@ -835,7 +835,7 @@ Literal Literal::div(const Literal& other) const { } Literal Literal::divS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 / other.i32); case Type::i64: @@ -846,7 +846,7 @@ Literal Literal::divS(const Literal& other) const { } Literal Literal::divU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) / uint32_t(other.i32)); case Type::i64: @@ -857,7 +857,7 @@ Literal Literal::divU(const Literal& other) const { } Literal Literal::remS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 % other.i32); case Type::i64: @@ -868,7 +868,7 @@ Literal Literal::remS(const Literal& other) const { } Literal Literal::remU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) % uint32_t(other.i32)); case Type::i64: @@ -896,7 +896,7 @@ Literal Literal::avgrUInt(const Literal& other) const { } Literal Literal::and_(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 & other.i32); case Type::i64: @@ -907,7 +907,7 @@ Literal Literal::and_(const Literal& other) const { } Literal Literal::or_(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 | other.i32); case Type::i64: @@ -918,7 +918,7 @@ Literal Literal::or_(const Literal& other) const { } Literal Literal::xor_(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 ^ other.i32); case Type::i64: @@ -929,7 +929,7 @@ Literal Literal::xor_(const Literal& other) const { } Literal Literal::shl(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) << Bits::getEffectiveShifts(other.i32, Type::i32)); @@ -942,7 +942,7 @@ Literal Literal::shl(const Literal& other) const { } Literal Literal::shrS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 >> Bits::getEffectiveShifts(other.i32, Type::i32)); case Type::i64: @@ -953,7 +953,7 @@ Literal Literal::shrS(const Literal& other) const { } Literal Literal::shrU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) >> Bits::getEffectiveShifts(other.i32, Type::i32)); @@ -966,7 +966,7 @@ Literal Literal::shrU(const Literal& other) const { } Literal Literal::rotL(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(RotateLeft(uint32_t(i32), uint32_t(other.i32))); case Type::i64: @@ -977,7 +977,7 @@ Literal Literal::rotL(const Literal& other) const { } Literal Literal::rotR(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(RotateRight(uint32_t(i32), uint32_t(other.i32))); case Type::i64: @@ -988,7 +988,7 @@ Literal Literal::rotR(const Literal& other) const { } Literal Literal::eq(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 == other.i32); case Type::i64: @@ -1010,7 +1010,7 @@ Literal Literal::eq(const Literal& other) const { } Literal Literal::ne(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 != other.i32); case Type::i64: @@ -1032,7 +1032,7 @@ Literal Literal::ne(const Literal& other) const { } Literal Literal::ltS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 < other.i32); case Type::i64: @@ -1043,7 +1043,7 @@ Literal Literal::ltS(const Literal& other) const { } Literal Literal::ltU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) < uint32_t(other.i32)); case Type::i64: @@ -1054,7 +1054,7 @@ Literal Literal::ltU(const Literal& other) const { } Literal Literal::lt(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(getf32() < other.getf32()); case Type::f64: @@ -1065,7 +1065,7 @@ Literal Literal::lt(const Literal& other) const { } Literal Literal::leS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 <= other.i32); case Type::i64: @@ -1076,7 +1076,7 @@ Literal Literal::leS(const Literal& other) const { } Literal Literal::leU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) <= uint32_t(other.i32)); case Type::i64: @@ -1087,7 +1087,7 @@ Literal Literal::leU(const Literal& other) const { } Literal Literal::le(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(getf32() <= other.getf32()); case Type::f64: @@ -1098,7 +1098,7 @@ Literal Literal::le(const Literal& other) const { } Literal Literal::gtS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 > other.i32); case Type::i64: @@ -1109,7 +1109,7 @@ Literal Literal::gtS(const Literal& other) const { } Literal Literal::gtU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) > uint32_t(other.i32)); case Type::i64: @@ -1120,7 +1120,7 @@ Literal Literal::gtU(const Literal& other) const { } Literal Literal::gt(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(getf32() > other.getf32()); case Type::f64: @@ -1131,7 +1131,7 @@ Literal Literal::gt(const Literal& other) const { } Literal Literal::geS(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(i32 >= other.i32); case Type::i64: @@ -1142,7 +1142,7 @@ Literal Literal::geS(const Literal& other) const { } Literal Literal::geU(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::i32: return Literal(uint32_t(i32) >= uint32_t(other.i32)); case Type::i64: @@ -1153,7 +1153,7 @@ Literal Literal::geU(const Literal& other) const { } Literal Literal::ge(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal(getf32() >= other.getf32()); case Type::f64: @@ -1164,7 +1164,7 @@ Literal Literal::ge(const Literal& other) const { } Literal Literal::min(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: { auto l = getf32(), r = other.getf32(); if (l == r && l == 0) { @@ -1207,7 +1207,7 @@ Literal Literal::min(const Literal& other) const { } Literal Literal::max(const Literal& other) const { - switch (type) { + switch (type.getSingle()) { case Type::f32: { auto l = getf32(), r = other.getf32(); if (l == r && l == 0) { @@ -1251,7 +1251,7 @@ Literal Literal::max(const Literal& other) const { Literal Literal::copysign(const Literal& other) const { // operate on bits directly, to avoid signalling bit being set on a float - switch (type) { + switch (type.getSingle()) { case Type::f32: return Literal((i32 & 0x7fffffff) | (other.i32 & 0x80000000)).castToF32(); break; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 551b1f132..a96dbb153 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -93,7 +93,7 @@ void BinaryInstWriter::visitGlobalSet(GlobalSet* curr) { void BinaryInstWriter::visitLoad(Load* curr) { if (!curr->isAtomic) { - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { switch (curr->bytes) { case 1: @@ -156,7 +156,7 @@ void BinaryInstWriter::visitLoad(Load* curr) { } } else { o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { switch (curr->bytes) { case 1: @@ -203,7 +203,7 @@ void BinaryInstWriter::visitLoad(Load* curr) { void BinaryInstWriter::visitStore(Store* curr) { if (!curr->isAtomic) { - switch (curr->valueType) { + switch (curr->valueType.getSingle()) { case Type::i32: { switch (curr->bytes) { case 1: @@ -259,7 +259,7 @@ void BinaryInstWriter::visitStore(Store* curr) { } } else { o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->valueType) { + switch (curr->valueType.getSingle()) { case Type::i32: { switch (curr->bytes) { case 1: @@ -307,7 +307,7 @@ void BinaryInstWriter::visitAtomicRMW(AtomicRMW* curr) { #define CASE_FOR_OP(Op) \ case Op: \ - switch (curr->type) { \ + switch (curr->type.getSingle()) { \ case Type::i32: \ switch (curr->bytes) { \ case 1: \ @@ -363,7 +363,7 @@ void BinaryInstWriter::visitAtomicRMW(AtomicRMW* curr) { void BinaryInstWriter::visitAtomicCmpxchg(AtomicCmpxchg* curr) { o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: switch (curr->bytes) { case 1: @@ -405,7 +405,7 @@ void BinaryInstWriter::visitAtomicCmpxchg(AtomicCmpxchg* curr) { void BinaryInstWriter::visitAtomicWait(AtomicWait* curr) { o << int8_t(BinaryConsts::AtomicPrefix); - switch (curr->expectedType) { + switch (curr->expectedType.getSingle()) { case Type::i32: { o << int8_t(BinaryConsts::I32AtomicWait); emitMemoryAccess(4, 4, curr->offset); @@ -621,7 +621,7 @@ void BinaryInstWriter::visitMemoryFill(MemoryFill* curr) { } void BinaryInstWriter::visitConst(Const* curr) { - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { o << int8_t(BinaryConsts::I32Const) << S32LEB(curr->value.geti32()); break; diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 62c30d1e0..3542f5d69 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -28,8 +28,8 @@ template<> class std::hash<std::vector<wasm::Type>> { public: size_t operator()(const std::vector<wasm::Type>& types) const { uint32_t res = wasm::rehash(0, uint32_t(types.size())); - for (auto vt : types) { - res = wasm::rehash(res, uint32_t(vt)); + for (auto t : types) { + res = wasm::rehash(res, t.getID()); } return res; } @@ -37,8 +37,8 @@ public: size_t std::hash<wasm::Signature>:: operator()(const wasm::Signature& sig) const { - return std::hash<uint64_t>{}(uint64_t(sig.params) << 32 | - uint64_t(sig.results)); + return std::hash<uint64_t>{}(uint64_t(sig.params.getID()) << 32 | + uint64_t(sig.results.getID())); } namespace wasm { @@ -141,13 +141,13 @@ bool Type::operator<(const Type& other) const { these.end(), others.begin(), others.end(), - [](const Type& a, const Type& b) { return uint32_t(a) < uint32_t(b); }); + [](const Type& a, const Type& b) { return a.getSingle() < b.getSingle(); }); } unsigned Type::getByteSize() const { assert(isSingle() && "getByteSize does not works with single types"); Type singleType = *expand().begin(); - switch (singleType) { + switch (singleType.getSingle()) { case Type::i32: return 4; case Type::i64: @@ -172,7 +172,7 @@ unsigned Type::getByteSize() const { Type Type::reinterpret() const { assert(isSingle() && "reinterpretType only works with single types"); Type singleType = *expand().begin(); - switch (singleType) { + switch (singleType.getSingle()) { case Type::i32: return f32; case Type::i64: @@ -196,7 +196,7 @@ Type Type::reinterpret() const { FeatureSet Type::getFeatures() const { FeatureSet feats = FeatureSet::MVP; for (Type t : expand()) { - switch (t) { + switch (t.getSingle()) { case Type::v128: feats |= FeatureSet::SIMD; break; @@ -299,50 +299,51 @@ bool Signature::operator<(const Signature& other) const { } std::ostream& operator<<(std::ostream& os, Type type) { - switch (type) { - case Type::none: - os << "none"; - break; - case Type::unreachable: - os << "unreachable"; - break; - case Type::i32: - os << "i32"; - break; - case Type::i64: - os << "i64"; - break; - case Type::f32: - os << "f32"; - break; - case Type::f64: - os << "f64"; - break; - case Type::v128: - os << "v128"; - break; - case Type::funcref: - os << "funcref"; - break; - case Type::anyref: - os << "anyref"; - break; - case Type::nullref: - os << "nullref"; - break; - case Type::exnref: - os << "exnref"; - break; - default: { - os << '('; - const std::vector<Type>& types = type.expand(); - for (size_t i = 0; i < types.size(); ++i) { - os << types[i]; - if (i < types.size() - 1) { - os << ", "; - } + if (type.isMulti()) { + os << '('; + const std::vector<Type>& types = type.expand(); + for (size_t i = 0; i < types.size(); ++i) { + os << types[i]; + if (i < types.size() - 1) { + os << ", "; } - os << ')'; + } + os << ')'; + } else { + switch (type.getSingle()) { + case Type::none: + os << "none"; + break; + case Type::unreachable: + os << "unreachable"; + break; + case Type::i32: + os << "i32"; + break; + case Type::i64: + os << "i64"; + break; + case Type::f32: + os << "f32"; + break; + case Type::f64: + os << "f64"; + break; + case Type::v128: + os << "v128"; + break; + case Type::funcref: + os << "funcref"; + break; + case Type::anyref: + os << "anyref"; + break; + case Type::nullref: + os << "nullref"; + break; + case Type::exnref: + os << "exnref"; + break; } } return os; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 30e182f0b..484376358 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -172,7 +172,7 @@ struct ValidationInfo { Expression* curr, const char* text, Function* func = nullptr) { - switch (ty) { + switch (ty.getSingle()) { case Type::i32: case Type::i64: case Type::unreachable: { @@ -1227,7 +1227,7 @@ void FunctionValidator::visitMemoryFill(MemoryFill* curr) { void FunctionValidator::validateMemBytes(uint8_t bytes, Type type, Expression* curr) { - switch (type) { + switch (type.getSingle()) { case Type::i32: shouldBeTrue(bytes == 1 || bytes == 2 || bytes == 4, curr, @@ -1975,7 +1975,7 @@ void FunctionValidator::validateAlignment( } } shouldBeTrue(align <= bytes, curr, "alignment must not exceed natural"); - switch (type) { + switch (type.getSingle()) { case Type::i32: case Type::f32: { shouldBeTrue(align <= 4, curr, "alignment must not exceed natural"); diff --git a/src/wasm2js.h b/src/wasm2js.h index 609373cca..55759c959 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -150,11 +150,11 @@ public: // Get a temp var. IString getTemp(Type type, Function* func) { IString ret; - if (frees[type].size() > 0) { - ret = frees[type].back(); - frees[type].pop_back(); + if (frees[type.getSingle()].size() > 0) { + ret = frees[type.getSingle()].back(); + frees[type.getSingle()].pop_back(); } else { - size_t index = temps[type]++; + size_t index = temps[type.getSingle()]++; ret = IString((std::string("wasm2js_") + type.toString() + "$" + std::to_string(index)) .c_str(), @@ -167,7 +167,9 @@ public: } // Free a temp var. - void freeTemp(Type type, IString temp) { frees[type].push_back(temp); } + void freeTemp(Type type, IString temp) { + frees[type.getSingle()].push_back(temp); + } // Generates a mangled name from `name` within the specified scope. // @@ -619,7 +621,7 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) { void Wasm2JSBuilder::addGlobal(Ref ast, Global* global) { if (auto* const_ = global->init->dynCast<Const>()) { Ref theValue; - switch (const_->type) { + switch (const_->type.getSingle()) { case Type::i32: { theValue = ValueBuilder::makeInt(const_->value.geti32()); break; @@ -1210,7 +1212,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, // normal load Ref ptr = makePointer(curr->ptr, curr->offset); Ref ret; - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { switch (curr->bytes) { case 1: @@ -1306,7 +1308,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref ptr = makePointer(curr->ptr, curr->offset); Ref value = visit(curr->value, EXPRESSION_RESULT); Ref ret; - switch (curr->valueType) { + switch (curr->valueType.getSingle()) { case Type::i32: { switch (curr->bytes) { case 1: @@ -1346,7 +1348,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref visitDrop(Drop* curr) { return visit(curr->value, NO_RESULT); } Ref visitConst(Const* curr) { - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: return ValueBuilder::makeInt(curr->value.geti32()); // An i64 argument translates to two actual arguments to asm.js @@ -1386,7 +1388,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref visitUnary(Unary* curr) { // normal unary - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { switch (curr->op) { case ClzInt32: { @@ -1545,7 +1547,7 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Ref left = visit(curr->left, EXPRESSION_RESULT); Ref right = visit(curr->right, EXPRESSION_RESULT); Ref ret; - switch (curr->type) { + switch (curr->type.getSingle()) { case Type::i32: { switch (curr->op) { case AddInt32: |