summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/wasm.h b/src/wasm.h
index 6c3efbfbe..52082f3a8 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -91,7 +91,10 @@ enum WasmType {
i32,
i64,
f32,
- f64
+ f64,
+ unreachable // none means no type, e.g. a block can have no return type. but
+ // unreachable is different, as it can be "ignored" when doing
+ // type checking across branches
};
inline const char* printWasmType(WasmType type) {
@@ -131,6 +134,10 @@ inline WasmType getWasmType(unsigned size, bool float_) {
abort();
}
+inline WasmType getReachableWasmType(WasmType a, WasmType b) {
+ return a != unreachable ? a : b;
+}
+
// Literals
struct Literal {
@@ -238,6 +245,7 @@ struct Literal {
case WasmType::i64: o << literal.i64; break;
case WasmType::f32: literal.printFloat(o, literal.f32); break;
case WasmType::f64: literal.printDouble(o, literal.f64); break;
+ default: WASM_UNREACHABLE();
}
restoreNormalColor(o);
return o << ')';
@@ -861,8 +869,8 @@ public:
if (isRelational()) {
type = i32;
} else {
- assert_node(left->type == right->type, this);
- type = left->type;
+ assert_node(left->type != unreachable && right->type != unreachable ? left->type == right->type : true, this);
+ type = getReachableWasmType(left->type, right->type);
}
}
};
@@ -931,7 +939,9 @@ public:
class Unreachable : public Expression {
public:
- Unreachable() : Expression(UnreachableId) {}
+ Unreachable() : Expression(UnreachableId) {
+ type = unreachable;
+ }
std::ostream& doPrint(std::ostream &o, unsigned indent) {
return printMinorOpening(o, "unreachable") << ')';