summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-01-08 17:43:25 -0800
committerGitHub <noreply@github.com>2020-01-08 17:43:25 -0800
commit77329439d6307d292e59986db3a194c3085abbe2 (patch)
treeac9f4ad3787f2e0d3644d34ff324a546380a17fd /src
parent8d4db9fb86c3b80df3eaa0d8e5eb379d081c8399 (diff)
downloadbinaryen-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')
-rw-r--r--src/asm2wasm.h4
-rw-r--r--src/asmjs/asm_v_wasm.cpp4
-rw-r--r--src/binaryen-c.cpp26
-rw-r--r--src/ir/ExpressionAnalyzer.cpp10
-rw-r--r--src/ir/ReFinalize.cpp2
-rw-r--r--src/ir/abstract.h4
-rw-r--r--src/ir/hashed.h6
-rw-r--r--src/literal.h8
-rw-r--r--src/parsing.h12
-rw-r--r--src/passes/ConstHoisting.cpp2
-rw-r--r--src/passes/FuncCastEmulation.cpp4
-rw-r--r--src/passes/I64ToI32Lowering.cpp4
-rw-r--r--src/passes/InstrumentLocals.cpp4
-rw-r--r--src/passes/InstrumentMemory.cpp4
-rw-r--r--src/passes/OptimizeInstructions.cpp6
-rw-r--r--src/passes/RemoveNonJSOps.cpp4
-rw-r--r--src/shell-interface.h2
-rw-r--r--src/tools/fuzzing.h26
-rw-r--r--src/tools/spec-wrapper.h2
-rw-r--r--src/tools/wasm-reduce.cpp10
-rw-r--r--src/tools/wasm2js.cpp2
-rw-r--r--src/wasm-binary.h2
-rw-r--r--src/wasm-builder.h4
-rw-r--r--src/wasm-interpreter.h4
-rw-r--r--src/wasm-type.h30
-rw-r--r--src/wasm/literal.cpp90
-rw-r--r--src/wasm/wasm-stack.cpp16
-rw-r--r--src/wasm/wasm-type.cpp103
-rw-r--r--src/wasm/wasm-validator.cpp6
-rw-r--r--src/wasm2js.h24
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: