summaryrefslogtreecommitdiff
path: root/src/wasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm.h')
-rw-r--r--src/wasm.h66
1 files changed, 46 insertions, 20 deletions
diff --git a/src/wasm.h b/src/wasm.h
index 6f889737b..c030d9d60 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -138,35 +138,58 @@ inline WasmType getReachableWasmType(WasmType a, WasmType b) {
return a != unreachable ? a : b;
}
+inline bool isConcreteWasmType(WasmType type) {
+ return type != none && type != unreachable;
+}
+
// Literals
-struct Literal {
+class Literal {
+public:
WasmType type;
+
+private:
+ // store only integers, whose bits are deterministic. floats
+ // can have their signalling bit set, for example.
union {
int32_t i32;
int64_t i64;
- float f32;
- double f64;
};
- Literal() : Literal(WasmType::none) {}
- explicit Literal(WasmType type) : type(type) { memset(&f64, 0, sizeof(f64)); }
+public:
+ Literal() : type(WasmType::none), i64(0) {}
+ explicit Literal(WasmType type) : type(type), i64(0) {}
explicit Literal(int32_t init) : type(WasmType::i32), i32(init) {}
explicit Literal(uint32_t init) : type(WasmType::i32), i32(init) {}
explicit Literal(int64_t init) : type(WasmType::i64), i64(init) {}
explicit Literal(uint64_t init) : type(WasmType::i64), i64(init) {}
- explicit Literal(float init) : type(WasmType::f32), f32(init) {}
- explicit Literal(double init) : type(WasmType::f64), f64(init) {}
+ explicit Literal(float init) : type(WasmType::f32), i32(bit_cast<int32_t>(init)) {}
+ explicit Literal(double init) : type(WasmType::f64), i64(bit_cast<int64_t>(init)) {}
+
+ Literal castToF32() {
+ assert(type == WasmType::i32);
+ Literal ret(i32);
+ ret.type = f32;
+ return ret;
+ }
+ Literal castToF64() {
+ assert(type == WasmType::i64);
+ Literal ret(i64);
+ ret.type = f64;
+ return ret;
+ }
int32_t geti32() { assert(type == WasmType::i32); return i32; }
int64_t geti64() { assert(type == WasmType::i64); return i64; }
- float getf32() { assert(type == WasmType::f32); return f32; }
- double getf64() { assert(type == WasmType::f64); return f64; }
+ float getf32() { assert(type == WasmType::f32); return bit_cast<float>(i32); }
+ double getf64() { assert(type == WasmType::f64); return bit_cast<double>(i64); }
+
+ int32_t* geti32Ptr() { assert(type == WasmType::i32); return &i32; } // careful!
int32_t reinterpreti32() { assert(type == WasmType::f32); return i32; }
int64_t reinterpreti64() { assert(type == WasmType::f64); return i64; }
- float reinterpretf32() { assert(type == WasmType::i32); return f32; }
- double reinterpretf64() { assert(type == WasmType::i64); return f64; }
+ float reinterpretf32() { assert(type == WasmType::i32); return bit_cast<float>(i32); }
+ double reinterpretf64() { assert(type == WasmType::i64); return bit_cast<double>(i64); }
int64_t getInteger() {
switch (type) {
@@ -178,8 +201,8 @@ struct Literal {
double getFloat() {
switch (type) {
- case WasmType::f32: return f32;
- case WasmType::f64: return f64;
+ case WasmType::f32: return getf32();
+ case WasmType::f64: return getf64();
default: abort();
}
}
@@ -189,10 +212,9 @@ struct Literal {
switch (type) {
case WasmType::none: return true;
case WasmType::i32: return i32 == other.i32;
+ case WasmType::f32: return getf32() == other.getf32();
case WasmType::i64: return i64 == other.i64;
- // reinterpret floating-point, to avoid nan != nan
- case WasmType::f32: return reinterpreti32() == other.reinterpreti32();
- case WasmType::f64: return reinterpreti64() == other.reinterpreti64();
+ case WasmType::f64: return getf64() == other.getf64();
default: abort();
}
}
@@ -244,8 +266,8 @@ struct Literal {
case none: o << "?"; break;
case WasmType::i32: o << literal.i32; break;
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;
+ case WasmType::f32: literal.printFloat(o, literal.getf32()); break;
+ case WasmType::f64: literal.printDouble(o, literal.getf64()); break;
default: WASM_UNREACHABLE();
}
restoreNormalColor(o);
@@ -479,7 +501,9 @@ public:
class Break : public Expression {
public:
- Break() : Expression(BreakId), condition(nullptr), value(nullptr) {}
+ Break() : Expression(BreakId), condition(nullptr), value(nullptr) {
+ type = unreachable;
+ }
Expression *condition;
Name name;
@@ -908,7 +932,9 @@ class Return : public Expression {
public:
Expression *value;
- Return() : Expression(ReturnId), value(nullptr) {}
+ Return() : Expression(ReturnId), value(nullptr) {
+ type = unreachable;
+ }
std::ostream& doPrint(std::ostream &o, unsigned indent) {
printOpening(o, "return");