diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/literal.cpp | 274 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 52 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 86 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 40 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 58 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 22 |
6 files changed, 266 insertions, 266 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index de89a7ac1..dca3d64b4 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -26,53 +26,53 @@ namespace wasm { Literal Literal::castToF32() { - assert(type == WasmType::i32); + assert(type == Type::i32); Literal ret(i32); - ret.type = WasmType::f32; + ret.type = Type::f32; return ret; } Literal Literal::castToF64() { - assert(type == WasmType::i64); + assert(type == Type::i64); Literal ret(i64); - ret.type = WasmType::f64; + ret.type = Type::f64; return ret; } Literal Literal::castToI32() { - assert(type == WasmType::f32); + assert(type == Type::f32); Literal ret(i32); - ret.type = WasmType::i32; + ret.type = Type::i32; return ret; } Literal Literal::castToI64() { - assert(type == WasmType::f64); + assert(type == Type::f64); Literal ret(i64); - ret.type = WasmType::i64; + ret.type = Type::i64; return ret; } int64_t Literal::getInteger() const { switch (type) { - case WasmType::i32: return i32; - case WasmType::i64: return i64; + case Type::i32: return i32; + case Type::i64: return i64; default: abort(); } } double Literal::getFloat() const { switch (type) { - case WasmType::f32: return getf32(); - case WasmType::f64: return getf64(); + case Type::f32: return getf32(); + case Type::f64: return getf64(); default: abort(); } } int64_t Literal::getBits() const { switch (type) { - case WasmType::i32: case WasmType::f32: return i32; - case WasmType::i64: case WasmType::f64: return i64; + case Type::i32: case Type::f32: return i32; + case Type::i64: case Type::f64: return i64; default: abort(); } } @@ -80,11 +80,11 @@ int64_t Literal::getBits() const { bool Literal::operator==(const Literal& other) const { if (type != other.type) return false; 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; - case WasmType::f64: return getf64() == other.getf64(); + case Type::none: return true; + case Type::i32: return i32 == other.i32; + case Type::f32: return getf32() == other.getf32(); + case Type::i64: return i64 == other.i64; + case Type::f64: return getf64() == other.getf64(); default: abort(); } } @@ -167,13 +167,13 @@ void Literal::printDouble(std::ostream& o, double d) { std::ostream& operator<<(std::ostream& o, Literal literal) { o << '('; - prepareMinorColor(o) << printWasmType(literal.type) << ".const "; + prepareMinorColor(o) << printType(literal.type) << ".const "; switch (literal.type) { 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.getf32()); break; - case WasmType::f64: literal.printDouble(o, literal.getf64()); break; + case Type::i32: o << literal.i32; break; + case Type::i64: o << literal.i64; break; + case Type::f32: literal.printFloat(o, literal.getf32()); break; + case Type::f64: literal.printDouble(o, literal.getf64()); break; default: WASM_UNREACHABLE(); } restoreNormalColor(o); @@ -181,165 +181,165 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { } Literal Literal::countLeadingZeroes() const { - if (type == WasmType::i32) return Literal((int32_t)CountLeadingZeroes(i32)); - if (type == WasmType::i64) return Literal((int64_t)CountLeadingZeroes(i64)); + if (type == Type::i32) return Literal((int32_t)CountLeadingZeroes(i32)); + if (type == Type::i64) return Literal((int64_t)CountLeadingZeroes(i64)); WASM_UNREACHABLE(); } Literal Literal::countTrailingZeroes() const { - if (type == WasmType::i32) return Literal((int32_t)CountTrailingZeroes(i32)); - if (type == WasmType::i64) return Literal((int64_t)CountTrailingZeroes(i64)); + if (type == Type::i32) return Literal((int32_t)CountTrailingZeroes(i32)); + if (type == Type::i64) return Literal((int64_t)CountTrailingZeroes(i64)); WASM_UNREACHABLE(); } Literal Literal::popCount() const { - if (type == WasmType::i32) return Literal((int32_t)PopCount(i32)); - if (type == WasmType::i64) return Literal((int64_t)PopCount(i64)); + if (type == Type::i32) return Literal((int32_t)PopCount(i32)); + if (type == Type::i64) return Literal((int64_t)PopCount(i64)); WASM_UNREACHABLE(); } Literal Literal::extendToSI64() const { - assert(type == WasmType::i32); + assert(type == Type::i32); return Literal((int64_t)i32); } Literal Literal::extendToUI64() const { - assert(type == WasmType::i32); + assert(type == Type::i32); return Literal((uint64_t)(uint32_t)i32); } Literal Literal::extendToF64() const { - assert(type == WasmType::f32); + assert(type == Type::f32); return Literal(double(getf32())); } Literal Literal::truncateToI32() const { - assert(type == WasmType::i64); + assert(type == Type::i64); return Literal((int32_t)i64); } Literal Literal::truncateToF32() const { - assert(type == WasmType::f64); + assert(type == Type::f64); return Literal(float(getf64())); } Literal Literal::convertSToF32() const { - if (type == WasmType::i32) return Literal(float(i32)); - if (type == WasmType::i64) return Literal(float(i64)); + if (type == Type::i32) return Literal(float(i32)); + if (type == Type::i64) return Literal(float(i64)); WASM_UNREACHABLE(); } Literal Literal::convertUToF32() const { - if (type == WasmType::i32) return Literal(float(uint32_t(i32))); - if (type == WasmType::i64) return Literal(float(uint64_t(i64))); + if (type == Type::i32) return Literal(float(uint32_t(i32))); + if (type == Type::i64) return Literal(float(uint64_t(i64))); WASM_UNREACHABLE(); } Literal Literal::convertSToF64() const { - if (type == WasmType::i32) return Literal(double(i32)); - if (type == WasmType::i64) return Literal(double(i64)); + if (type == Type::i32) return Literal(double(i32)); + if (type == Type::i64) return Literal(double(i64)); WASM_UNREACHABLE(); } Literal Literal::convertUToF64() const { - if (type == WasmType::i32) return Literal(double(uint32_t(i32))); - if (type == WasmType::i64) return Literal(double(uint64_t(i64))); + if (type == Type::i32) return Literal(double(uint32_t(i32))); + if (type == Type::i64) return Literal(double(uint64_t(i64))); WASM_UNREACHABLE(); } Literal Literal::neg() const { switch (type) { - case WasmType::i32: return Literal(i32 ^ 0x80000000); - case WasmType::i64: return Literal(int64_t(i64 ^ 0x8000000000000000ULL)); - case WasmType::f32: return Literal(i32 ^ 0x80000000).castToF32(); - case WasmType::f64: return Literal(int64_t(i64 ^ 0x8000000000000000ULL)).castToF64(); + case Type::i32: return Literal(i32 ^ 0x80000000); + case Type::i64: return Literal(int64_t(i64 ^ 0x8000000000000000ULL)); + case Type::f32: return Literal(i32 ^ 0x80000000).castToF32(); + case Type::f64: return Literal(int64_t(i64 ^ 0x8000000000000000ULL)).castToF64(); default: WASM_UNREACHABLE(); } } Literal Literal::abs() const { switch (type) { - case WasmType::i32: return Literal(i32 & 0x7fffffff); - case WasmType::i64: return Literal(int64_t(i64 & 0x7fffffffffffffffULL)); - case WasmType::f32: return Literal(i32 & 0x7fffffff).castToF32(); - case WasmType::f64: return Literal(int64_t(i64 & 0x7fffffffffffffffULL)).castToF64(); + case Type::i32: return Literal(i32 & 0x7fffffff); + case Type::i64: return Literal(int64_t(i64 & 0x7fffffffffffffffULL)); + case Type::f32: return Literal(i32 & 0x7fffffff).castToF32(); + case Type::f64: return Literal(int64_t(i64 & 0x7fffffffffffffffULL)).castToF64(); default: WASM_UNREACHABLE(); } } Literal Literal::ceil() const { switch (type) { - case WasmType::f32: return Literal(std::ceil(getf32())); - case WasmType::f64: return Literal(std::ceil(getf64())); + case Type::f32: return Literal(std::ceil(getf32())); + case Type::f64: return Literal(std::ceil(getf64())); default: WASM_UNREACHABLE(); } } Literal Literal::floor() const { switch (type) { - case WasmType::f32: return Literal(std::floor(getf32())); - case WasmType::f64: return Literal(std::floor(getf64())); + case Type::f32: return Literal(std::floor(getf32())); + case Type::f64: return Literal(std::floor(getf64())); default: WASM_UNREACHABLE(); } } Literal Literal::trunc() const { switch (type) { - case WasmType::f32: return Literal(std::trunc(getf32())); - case WasmType::f64: return Literal(std::trunc(getf64())); + case Type::f32: return Literal(std::trunc(getf32())); + case Type::f64: return Literal(std::trunc(getf64())); default: WASM_UNREACHABLE(); } } Literal Literal::nearbyint() const { switch (type) { - case WasmType::f32: return Literal(std::nearbyint(getf32())); - case WasmType::f64: return Literal(std::nearbyint(getf64())); + case Type::f32: return Literal(std::nearbyint(getf32())); + case Type::f64: return Literal(std::nearbyint(getf64())); default: WASM_UNREACHABLE(); } } Literal Literal::sqrt() const { switch (type) { - case WasmType::f32: return Literal(std::sqrt(getf32())); - case WasmType::f64: return Literal(std::sqrt(getf64())); + case Type::f32: return Literal(std::sqrt(getf32())); + case Type::f64: return Literal(std::sqrt(getf64())); default: WASM_UNREACHABLE(); } } Literal Literal::add(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) + uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) + uint64_t(other.i64)); - case WasmType::f32: return Literal(getf32() + other.getf32()); - case WasmType::f64: return Literal(getf64() + other.getf64()); + case Type::i32: return Literal(uint32_t(i32) + uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) + uint64_t(other.i64)); + case Type::f32: return Literal(getf32() + other.getf32()); + case Type::f64: return Literal(getf64() + other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::sub(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) - uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) - uint64_t(other.i64)); - case WasmType::f32: return Literal(getf32() - other.getf32()); - case WasmType::f64: return Literal(getf64() - other.getf64()); + case Type::i32: return Literal(uint32_t(i32) - uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) - uint64_t(other.i64)); + case Type::f32: return Literal(getf32() - other.getf32()); + case Type::f64: return Literal(getf64() - other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::mul(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) * uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) * uint64_t(other.i64)); - case WasmType::f32: return Literal(getf32() * other.getf32()); - case WasmType::f64: return Literal(getf64() * other.getf64()); + case Type::i32: return Literal(uint32_t(i32) * uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) * uint64_t(other.i64)); + case Type::f32: return Literal(getf32() * other.getf32()); + case Type::f64: return Literal(getf64() * other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::div(const Literal& other) const { switch (type) { - case WasmType::f32: { + case Type::f32: { float lhs = getf32(), rhs = other.getf32(); float sign = std::signbit(lhs) == std::signbit(rhs) ? 0.f : -0.f; switch (std::fpclassify(rhs)) { @@ -359,7 +359,7 @@ Literal Literal::div(const Literal& other) const { default: WASM_UNREACHABLE(); } } - case WasmType::f64: { + case Type::f64: { double lhs = getf64(), rhs = other.getf64(); double sign = std::signbit(lhs) == std::signbit(rhs) ? 0. : -0.; switch (std::fpclassify(rhs)) { @@ -385,219 +385,219 @@ Literal Literal::div(const Literal& other) const { Literal Literal::divS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 / other.i32); - case WasmType::i64: return Literal(i64 / other.i64); + case Type::i32: return Literal(i32 / other.i32); + case Type::i64: return Literal(i64 / other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::divU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) / uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) / uint64_t(other.i64)); + case Type::i32: return Literal(uint32_t(i32) / uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) / uint64_t(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::remS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 % other.i32); - case WasmType::i64: return Literal(i64 % other.i64); + case Type::i32: return Literal(i32 % other.i32); + case Type::i64: return Literal(i64 % other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::remU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) % uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) % uint64_t(other.i64)); + case Type::i32: return Literal(uint32_t(i32) % uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) % uint64_t(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::and_(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 & other.i32); - case WasmType::i64: return Literal(i64 & other.i64); + case Type::i32: return Literal(i32 & other.i32); + case Type::i64: return Literal(i64 & other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::or_(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 | other.i32); - case WasmType::i64: return Literal(i64 | other.i64); + case Type::i32: return Literal(i32 | other.i32); + case Type::i64: return Literal(i64 | other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::xor_(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 ^ other.i32); - case WasmType::i64: return Literal(i64 ^ other.i64); + case Type::i32: return Literal(i32 ^ other.i32); + case Type::i64: return Literal(i64 ^ other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::shl(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) << shiftMask(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) << shiftMask(other.i64)); + case Type::i32: return Literal(uint32_t(i32) << shiftMask(other.i32)); + case Type::i64: return Literal(uint64_t(i64) << shiftMask(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::shrS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 >> shiftMask(other.i32)); - case WasmType::i64: return Literal(i64 >> shiftMask(other.i64)); + case Type::i32: return Literal(i32 >> shiftMask(other.i32)); + case Type::i64: return Literal(i64 >> shiftMask(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::shrU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) >> shiftMask(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) >> shiftMask(other.i64)); + case Type::i32: return Literal(uint32_t(i32) >> shiftMask(other.i32)); + case Type::i64: return Literal(uint64_t(i64) >> shiftMask(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::rotL(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(RotateLeft(uint32_t(i32), uint32_t(other.i32))); - case WasmType::i64: return Literal(RotateLeft(uint64_t(i64), uint64_t(other.i64))); + case Type::i32: return Literal(RotateLeft(uint32_t(i32), uint32_t(other.i32))); + case Type::i64: return Literal(RotateLeft(uint64_t(i64), uint64_t(other.i64))); default: WASM_UNREACHABLE(); } } Literal Literal::rotR(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(RotateRight(uint32_t(i32), uint32_t(other.i32))); - case WasmType::i64: return Literal(RotateRight(uint64_t(i64), uint64_t(other.i64))); + case Type::i32: return Literal(RotateRight(uint32_t(i32), uint32_t(other.i32))); + case Type::i64: return Literal(RotateRight(uint64_t(i64), uint64_t(other.i64))); default: WASM_UNREACHABLE(); } } Literal Literal::eq(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 == other.i32); - case WasmType::i64: return Literal(i64 == other.i64); - case WasmType::f32: return Literal(getf32() == other.getf32()); - case WasmType::f64: return Literal(getf64() == other.getf64()); + case Type::i32: return Literal(i32 == other.i32); + case Type::i64: return Literal(i64 == other.i64); + case Type::f32: return Literal(getf32() == other.getf32()); + case Type::f64: return Literal(getf64() == other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::ne(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 != other.i32); - case WasmType::i64: return Literal(i64 != other.i64); - case WasmType::f32: return Literal(getf32() != other.getf32()); - case WasmType::f64: return Literal(getf64() != other.getf64()); + case Type::i32: return Literal(i32 != other.i32); + case Type::i64: return Literal(i64 != other.i64); + case Type::f32: return Literal(getf32() != other.getf32()); + case Type::f64: return Literal(getf64() != other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::ltS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 < other.i32); - case WasmType::i64: return Literal(i64 < other.i64); + case Type::i32: return Literal(i32 < other.i32); + case Type::i64: return Literal(i64 < other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::ltU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) < uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) < uint64_t(other.i64)); + case Type::i32: return Literal(uint32_t(i32) < uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) < uint64_t(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::lt(const Literal& other) const { switch (type) { - case WasmType::f32: return Literal(getf32() < other.getf32()); - case WasmType::f64: return Literal(getf64() < other.getf64()); + case Type::f32: return Literal(getf32() < other.getf32()); + case Type::f64: return Literal(getf64() < other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::leS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 <= other.i32); - case WasmType::i64: return Literal(i64 <= other.i64); + case Type::i32: return Literal(i32 <= other.i32); + case Type::i64: return Literal(i64 <= other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::leU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) <= uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) <= uint64_t(other.i64)); + case Type::i32: return Literal(uint32_t(i32) <= uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) <= uint64_t(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::le(const Literal& other) const { switch (type) { - case WasmType::f32: return Literal(getf32() <= other.getf32()); - case WasmType::f64: return Literal(getf64() <= other.getf64()); + case Type::f32: return Literal(getf32() <= other.getf32()); + case Type::f64: return Literal(getf64() <= other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::gtS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 > other.i32); - case WasmType::i64: return Literal(i64 > other.i64); + case Type::i32: return Literal(i32 > other.i32); + case Type::i64: return Literal(i64 > other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::gtU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) > uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) > uint64_t(other.i64)); + case Type::i32: return Literal(uint32_t(i32) > uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) > uint64_t(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::gt(const Literal& other) const { switch (type) { - case WasmType::f32: return Literal(getf32() > other.getf32()); - case WasmType::f64: return Literal(getf64() > other.getf64()); + case Type::f32: return Literal(getf32() > other.getf32()); + case Type::f64: return Literal(getf64() > other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::geS(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(i32 >= other.i32); - case WasmType::i64: return Literal(i64 >= other.i64); + case Type::i32: return Literal(i32 >= other.i32); + case Type::i64: return Literal(i64 >= other.i64); default: WASM_UNREACHABLE(); } } Literal Literal::geU(const Literal& other) const { switch (type) { - case WasmType::i32: return Literal(uint32_t(i32) >= uint32_t(other.i32)); - case WasmType::i64: return Literal(uint64_t(i64) >= uint64_t(other.i64)); + case Type::i32: return Literal(uint32_t(i32) >= uint32_t(other.i32)); + case Type::i64: return Literal(uint64_t(i64) >= uint64_t(other.i64)); default: WASM_UNREACHABLE(); } } Literal Literal::ge(const Literal& other) const { switch (type) { - case WasmType::f32: return Literal(getf32() >= other.getf32()); - case WasmType::f64: return Literal(getf64() >= other.getf64()); + case Type::f32: return Literal(getf32() >= other.getf32()); + case Type::f64: return Literal(getf64() >= other.getf64()); default: WASM_UNREACHABLE(); } } Literal Literal::min(const Literal& other) const { switch (type) { - case WasmType::f32: { + case Type::f32: { auto l = getf32(), r = other.getf32(); if (l == r && l == 0) return Literal(std::signbit(l) ? l : r); auto result = std::min(l, r); @@ -606,7 +606,7 @@ Literal Literal::min(const Literal& other) const { if (!lnan && !rnan) return Literal((int32_t)0x7fc00000).castToF32(); return Literal(lnan ? l : r).castToI32().or_(Literal(0xc00000)).castToF32(); } - case WasmType::f64: { + case Type::f64: { auto l = getf64(), r = other.getf64(); if (l == r && l == 0) return Literal(std::signbit(l) ? l : r); auto result = std::min(l, r); @@ -621,7 +621,7 @@ Literal Literal::min(const Literal& other) const { Literal Literal::max(const Literal& other) const { switch (type) { - case WasmType::f32: { + case Type::f32: { auto l = getf32(), r = other.getf32(); if (l == r && l == 0) return Literal(std::signbit(l) ? r : l); auto result = std::max(l, r); @@ -630,7 +630,7 @@ Literal Literal::max(const Literal& other) const { if (!lnan && !rnan) return Literal((int32_t)0x7fc00000).castToF32(); return Literal(lnan ? l : r).castToI32().or_(Literal(0xc00000)).castToF32(); } - case WasmType::f64: { + case Type::f64: { auto l = getf64(), r = other.getf64(); if (l == r && l == 0) return Literal(std::signbit(l) ? r : l); auto result = std::max(l, r); @@ -646,8 +646,8 @@ 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) { - case WasmType::f32: return Literal((i32 & 0x7fffffff) | (other.i32 & 0x80000000)).castToF32(); break; - case WasmType::f64: return Literal((i64 & 0x7fffffffffffffffUL) | (other.i64 & 0x8000000000000000UL)).castToF64(); break; + case Type::f32: return Literal((i32 & 0x7fffffff) | (other.i32 & 0x80000000)).castToF32(); break; + case Type::f64: return Literal((i64 & 0x7fffffffffffffffUL) | (other.i64 & 0x8000000000000000UL)).castToF64(); break; default: WASM_UNREACHABLE(); } } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 19f84f98c..188c2bc17 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -145,13 +145,13 @@ void WasmBinaryWriter::writeTypes() { o << S32LEB(BinaryConsts::EncodedType::Func); o << U32LEB(type->params.size()); for (auto param : type->params) { - o << binaryWasmType(param); + o << binaryType(param); } if (type->result == none) { o << U32LEB(0); } else { o << U32LEB(1); - o << binaryWasmType(type->result); + o << binaryType(type->result); } } finishSection(start); @@ -188,7 +188,7 @@ void WasmBinaryWriter::writeImports() { break; } case ExternalKind::Global: - o << binaryWasmType(import->globalType); + o << binaryType(import->globalType); o << U32LEB(0); // Mutable global's can't be imported for now. break; default: WASM_UNREACHABLE(); @@ -205,10 +205,10 @@ void WasmBinaryWriter::mapLocals(Function* function) { for (auto type : function->vars) { numLocalsByType[type]++; } - std::map<WasmType, size_t> currLocalsByType; + std::map<Type, size_t> currLocalsByType; for (Index i = function->getVarIndexBase(); i < function->getNumLocals(); i++) { size_t index = function->getVarIndexBase(); - WasmType type = function->getLocalType(i); + Type type = function->getLocalType(i); currLocalsByType[type]++; // increment now for simplicity, must decrement it in returns if (type == i32) { mappedLocals[i] = index + currLocalsByType[i32] - 1; @@ -273,10 +273,10 @@ void WasmBinaryWriter::writeFunctions() { (numLocalsByType[f32] ? 1 : 0) + (numLocalsByType[f64] ? 1 : 0) ); - if (numLocalsByType[i32]) o << U32LEB(numLocalsByType[i32]) << binaryWasmType(i32); - if (numLocalsByType[i64]) o << U32LEB(numLocalsByType[i64]) << binaryWasmType(i64); - if (numLocalsByType[f32]) o << U32LEB(numLocalsByType[f32]) << binaryWasmType(f32); - if (numLocalsByType[f64]) o << U32LEB(numLocalsByType[f64]) << binaryWasmType(f64); + if (numLocalsByType[i32]) o << U32LEB(numLocalsByType[i32]) << binaryType(i32); + if (numLocalsByType[i64]) o << U32LEB(numLocalsByType[i64]) << binaryType(i64); + if (numLocalsByType[f32]) o << U32LEB(numLocalsByType[f32]) << binaryType(f32); + if (numLocalsByType[f64]) o << U32LEB(numLocalsByType[f64]) << binaryType(f64); recursePossibleBlockContents(function->body); o << int8_t(BinaryConsts::End); @@ -303,7 +303,7 @@ void WasmBinaryWriter::writeGlobals() { o << U32LEB(wasm->globals.size()); for (auto& curr : wasm->globals) { if (debug) std::cerr << "write one" << std::endl; - o << binaryWasmType(curr->type); + o << binaryType(curr->type); o << U32LEB(curr->mutable_); writeExpression(curr->init); o << int8_t(BinaryConsts::End); @@ -628,7 +628,7 @@ static bool brokenTo(Block* block) { void WasmBinaryWriter::visitBlock(Block *curr) { if (debug) std::cerr << "zz node: Block" << std::endl; o << int8_t(BinaryConsts::Block); - o << binaryWasmType(curr->type != unreachable ? curr->type : none); + o << binaryType(curr->type != unreachable ? curr->type : none); breakStack.push_back(curr->name); Index i = 0; for (auto* child : curr->list) { @@ -678,7 +678,7 @@ void WasmBinaryWriter::visitIf(If *curr) { } recurse(curr->condition); o << int8_t(BinaryConsts::If); - o << binaryWasmType(curr->type != unreachable ? curr->type : none); + o << binaryType(curr->type != unreachable ? curr->type : none); breakStack.push_back(IMPOSSIBLE_CONTINUE); // the binary format requires this; we have a block if we need one; TODO: optimize recursePossibleBlockContents(curr->ifTrue); // TODO: emit block contents directly, if possible breakStack.pop_back(); @@ -701,7 +701,7 @@ void WasmBinaryWriter::visitIf(If *curr) { void WasmBinaryWriter::visitLoop(Loop *curr) { if (debug) std::cerr << "zz node: Loop" << std::endl; o << int8_t(BinaryConsts::Loop); - o << binaryWasmType(curr->type != unreachable ? curr->type : none); + o << binaryType(curr->type != unreachable ? curr->type : none); breakStack.push_back(curr->name); recursePossibleBlockContents(curr->body); breakStack.pop_back(); @@ -1478,7 +1478,7 @@ int64_t WasmBinaryBuilder::getS64LEB() { return ret.value; } -WasmType WasmBinaryBuilder::getWasmType() { +Type WasmBinaryBuilder::getType() { int type = getS32LEB(); switch (type) { // None only used for block signatures. TODO: Separate out? @@ -1579,7 +1579,7 @@ void WasmBinaryBuilder::readSignatures() { size_t numParams = getU32LEB(); if (debug) std::cerr << "num params: " << numParams << std::endl; for (size_t j = 0; j < numParams; j++) { - curr->params.push_back(getWasmType()); + curr->params.push_back(getType()); } auto numResults = getU32LEB(); if (numResults == 0) { @@ -1588,7 +1588,7 @@ void WasmBinaryBuilder::readSignatures() { if (numResults != 1) { throw ParseException("signature must have 1 result"); } - curr->result = getWasmType(); + curr->result = getType(); } curr->name = Name::fromInt(wasm.functionTypes.size()); wasm.addFunctionType(curr); @@ -1661,7 +1661,7 @@ void WasmBinaryBuilder::readImports() { break; } case ExternalKind::Global: { - curr->globalType = getWasmType(); + curr->globalType = getType(); auto globalMutable = getU32LEB(); // TODO: actually use the globalMutable flag. Currently mutable global // imports is a future feature, to be implemented with thread support. @@ -1717,7 +1717,7 @@ void WasmBinaryBuilder::readFunctions() { size_t numLocalTypes = getU32LEB(); for (size_t t = 0; t < numLocalTypes; t++) { auto num = getU32LEB(); - auto type = getWasmType(); + auto type = getType(); while (num > 0) { vars.emplace_back(addVar(), type); num--; @@ -1925,7 +1925,7 @@ void WasmBinaryBuilder::readGlobals() { if (debug) std::cerr << "num: " << num << std::endl; for (size_t i = 0; i < num; i++) { if (debug) std::cerr << "read one" << std::endl; - auto type = getWasmType(); + auto type = getType(); auto mutable_ = getU32LEB(); if (bool(mutable_) != mutable_) throw ParseException("Global mutability must be 0 or 1"); auto* init = readExpression(); @@ -2302,7 +2302,7 @@ void WasmBinaryBuilder::pushBlockElements(Block* curr, size_t start, size_t end) curr->list.push_back(item); if (i < end - 1) { // stacky&unreachable code may introduce elements that need to be dropped in non-final positions - if (isConcreteWasmType(item->type)) { + if (isConcreteType(item->type)) { curr->list.back() = Builder(wasm).makeDrop(item); if (consumable == NONE) { // this is the first, and hence consumable value. note the location @@ -2331,7 +2331,7 @@ void WasmBinaryBuilder::visitBlock(Block *curr) { // a common pattern that can be very highly nested. std::vector<Block*> stack; while (1) { - curr->type = getWasmType(); + curr->type = getType(); curr->name = getNextLabel(); breakStack.push_back({curr->name, curr->type != none}); stack.push_back(curr); @@ -2367,7 +2367,7 @@ void WasmBinaryBuilder::visitBlock(Block *curr) { } } -Expression* WasmBinaryBuilder::getBlockOrSingleton(WasmType type) { +Expression* WasmBinaryBuilder::getBlockOrSingleton(Type type) { Name label = getNextLabel(); breakStack.push_back({label, type != none && type != unreachable}); auto start = expressionStack.size(); @@ -2394,7 +2394,7 @@ Expression* WasmBinaryBuilder::getBlockOrSingleton(WasmType type) { void WasmBinaryBuilder::visitIf(If *curr) { if (debug) std::cerr << "zz node: If" << std::endl; - curr->type = getWasmType(); + curr->type = getType(); curr->condition = popNonVoidExpression(); curr->ifTrue = getBlockOrSingleton(curr->type); if (lastSeparator == BinaryConsts::Else) { @@ -2408,7 +2408,7 @@ void WasmBinaryBuilder::visitIf(If *curr) { void WasmBinaryBuilder::visitLoop(Loop *curr) { if (debug) std::cerr << "zz node: Loop" << std::endl; - curr->type = getWasmType(); + curr->type = getType(); curr->name = getNextLabel(); breakStack.push_back({curr->name, 0}); // find the expressions in the block, and create the body @@ -2759,7 +2759,7 @@ bool WasmBinaryBuilder::maybeVisitAtomicWait(Expression*& out, uint8_t code) { curr->ptr = popNonVoidExpression(); Address readAlign; readMemoryAccess(readAlign, curr->offset); - if (readAlign != getWasmTypeSize(curr->expectedType)) throw ParseException("Align of AtomicWait must match size"); + if (readAlign != getTypeSize(curr->expectedType)) throw ParseException("Align of AtomicWait must match size"); curr->finalize(); out = curr; return true; @@ -2775,7 +2775,7 @@ bool WasmBinaryBuilder::maybeVisitAtomicWake(Expression*& out, uint8_t code) { curr->ptr = popNonVoidExpression(); Address readAlign; readMemoryAccess(readAlign, curr->offset); - if (readAlign != getWasmTypeSize(curr->type)) throw ParseException("Align of AtomicWake must match size"); + if (readAlign != getTypeSize(curr->type)) throw ParseException("Align of AtomicWake must match size"); curr->finalize(); out = curr; return true; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 0de3edf3f..5033047b0 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -377,13 +377,13 @@ void SExpressionWasmBuilder::preParseFunctionType(Element& s) { functionCounter++; FunctionType* type = nullptr; functionTypes[name] = none; - std::vector<WasmType> params; + std::vector<Type> params; for (;i < s.size(); i++) { Element& curr = *s[i]; IString id = curr[0]->str(); if (id == RESULT) { if (curr.size() > 2) throw ParseException("invalid result arity", curr.line, curr.col); - functionTypes[name] = stringToWasmType(curr[1]->str()); + functionTypes[name] = stringToType(curr[1]->str()); } else if (id == TYPE) { Name typeName = getFunctionTypeName(*curr[1]); if (!wasm.getFunctionTypeOrNull(typeName)) throw ParseException("unknown function type", curr.line, curr.col); @@ -393,10 +393,10 @@ void SExpressionWasmBuilder::preParseFunctionType(Element& s) { Index j = 1; if (curr[j]->dollared()) { // dollared input symbols cannot be types - params.push_back(stringToWasmType(curr[j + 1]->str(), true)); + params.push_back(stringToType(curr[j + 1]->str(), true)); } else { while (j < curr.size()) { - params.push_back(stringToWasmType(curr[j++]->str(), true)); + params.push_back(stringToType(curr[j++]->str(), true)); } } } @@ -485,7 +485,7 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { std::vector<NameType> typeParams; // we may have both params and a type. store the type info here std::vector<NameType> params; std::vector<NameType> vars; - WasmType result = none; + Type result = none; Name type; Block* autoBlock = nullptr; // we may need to add a block for the very top level Name importModule, importBase; @@ -511,16 +511,16 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { size_t j = 1; while (j < curr.size()) { IString name; - WasmType type = none; + Type type = none; if (!curr[j]->dollared()) { // dollared input symbols cannot be types - type = stringToWasmType(curr[j]->str(), true); + type = stringToType(curr[j]->str(), true); } if (type != none) { // a type, so an unnamed parameter name = Name::fromInt(localIndex); } else { name = curr[j]->str(); - type = stringToWasmType(curr[j+1]->str()); + type = stringToType(curr[j+1]->str()); j++; } j++; @@ -534,7 +534,7 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { } } else if (id == RESULT) { if (curr.size() > 2) throw ParseException("invalid result arity", curr.line, curr.col); - result = stringToWasmType(curr[1]->str()); + result = stringToType(curr[1]->str()); } else if (id == TYPE) { Name name = getFunctionTypeName(*curr[1]); type = name; @@ -543,7 +543,7 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { result = type->result; for (size_t j = 0; j < type->params.size(); j++) { IString name = Name::fromInt(j); - WasmType currType = type->params[j]; + Type currType = type->params[j]; typeParams.emplace_back(name, currType); currLocalTypes[name] = currType; } @@ -614,7 +614,7 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { nameMapper.clear(); } -WasmType SExpressionWasmBuilder::stringToWasmType(const char* str, bool allowError, bool prefix) { +Type SExpressionWasmBuilder::stringToType(const char* str, bool allowError, bool prefix) { if (str[0] == 'i') { if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) return i32; if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) return i64; @@ -650,7 +650,7 @@ Expression* SExpressionWasmBuilder::makeExpression(Element& s) { const char *dot = strchr(str, '.'); if (dot) { // type.operation (e.g. i32.add) - WasmType type = stringToWasmType(str, false, true); + Type type = stringToType(str, false, true); // Local copy to index into op without bounds checking. enum { maxNameSize = 15 }; char op[maxNameSize + 1] = {'\0'}; @@ -760,7 +760,7 @@ Expression* SExpressionWasmBuilder::makeExpression(Element& s) { case 'r': { if (op[1] == 'e') { if (op[2] == 'm') return makeBinary(s, op[4] == 'u' ? BINARY_INT(RemU) : BINARY_INT(RemS), type); - if (op[2] == 'i') return makeUnary(s, isWasmTypeFloat(type) ? (type == f32 ? UnaryOp::ReinterpretInt32 : UnaryOp::ReinterpretInt64) : (type == i32 ? UnaryOp::ReinterpretFloat32 : UnaryOp::ReinterpretFloat64), type); + if (op[2] == 'i') return makeUnary(s, isTypeFloat(type) ? (type == f32 ? UnaryOp::ReinterpretInt32 : UnaryOp::ReinterpretInt64) : (type == i32 ? UnaryOp::ReinterpretFloat32 : UnaryOp::ReinterpretFloat64), type); } if (op[1] == 'o' && op[2] == 't') { return makeBinary(s, op[3] == 'l' ? BINARY_INT(RotL) : BINARY_INT(RotR), type); @@ -882,7 +882,7 @@ Expression* SExpressionWasmBuilder::makeExpression(Element& s) { abort_on("unrecognized input string for parsing"); } -Expression* SExpressionWasmBuilder::makeBinary(Element& s, BinaryOp op, WasmType type) { +Expression* SExpressionWasmBuilder::makeBinary(Element& s, BinaryOp op, Type type) { auto ret = allocator.alloc<Binary>(); ret->op = op; ret->left = parseExpression(s[1]); @@ -892,7 +892,7 @@ Expression* SExpressionWasmBuilder::makeBinary(Element& s, BinaryOp op, WasmType } -Expression* SExpressionWasmBuilder::makeUnary(Element& s, UnaryOp op, WasmType type) { +Expression* SExpressionWasmBuilder::makeUnary(Element& s, UnaryOp op, Type type) { auto ret = allocator.alloc<Unary>(); ret->op = op; ret->value = parseExpression(s[1]); @@ -922,7 +922,7 @@ Expression* SExpressionWasmBuilder::makeUnary(Element& s, UnaryOp op, WasmType t case ClzInt64: case CtzInt64: case PopcntInt64: { - if (ret->value->type != unreachable && type != ret->value->type) throw ParseException(std::string("bad type for ") + getExpressionName(ret) + ": " + printWasmType(type) + " vs value type " + printWasmType(ret->value->type), s.line, s.col); + if (ret->value->type != unreachable && type != ret->value->type) throw ParseException(std::string("bad type for ") + getExpressionName(ret) + ": " + printType(type) + " vs value type " + printType(ret->value->type), s.line, s.col); break; } case ExtendSInt32: case ExtendUInt32: @@ -1069,7 +1069,7 @@ Expression* SExpressionWasmBuilder::makeBlock(Element& s) { Name sName; if (i < s.size() && s[i]->isStr()) { // could be a name or a type - if (s[i]->dollared() || stringToWasmType(s[i]->str(), true /* allowError */) == none) { + if (s[i]->dollared() || stringToType(s[i]->str(), true /* allowError */) == none) { sName = s[i++]->str(); } else { sName = "block"; @@ -1132,7 +1132,7 @@ Expression* SExpressionWasmBuilder::makeThenOrElse(Element& s) { return ret; } -Expression* SExpressionWasmBuilder::makeConst(Element& s, WasmType type) { +Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) { auto ret = parseConst(s[1]->str(), type, allocator); if (!ret) throw ParseException("bad const"); return ret; @@ -1180,13 +1180,13 @@ static size_t parseMemAttributes(Element& s, Address* offset, Address* align, Ad return i; } -Expression* SExpressionWasmBuilder::makeLoad(Element& s, WasmType type, bool isAtomic) { +Expression* SExpressionWasmBuilder::makeLoad(Element& s, Type type, bool isAtomic) { const char *extra = strchr(s[0]->c_str(), '.') + 5; // after "type.load" if (isAtomic) extra += 7; // after "type.atomic.load" auto* ret = allocator.alloc<Load>(); ret->isAtomic = isAtomic; ret->type = type; - ret->bytes = parseMemBytes(&extra, getWasmTypeSize(type)); + ret->bytes = parseMemBytes(&extra, getTypeSize(type)); ret->signed_ = extra[0] && extra[1] == 's'; size_t i = parseMemAttributes(s, &ret->offset, &ret->align, ret->bytes); ret->ptr = parseExpression(s[i]); @@ -1194,13 +1194,13 @@ Expression* SExpressionWasmBuilder::makeLoad(Element& s, WasmType type, bool isA return ret; } -Expression* SExpressionWasmBuilder::makeStore(Element& s, WasmType type, bool isAtomic) { +Expression* SExpressionWasmBuilder::makeStore(Element& s, Type type, bool isAtomic) { const char *extra = strchr(s[0]->c_str(), '.') + 6; // after "type.store" if (isAtomic) extra += 7; // after "type.atomic.store" auto ret = allocator.alloc<Store>(); ret->isAtomic = isAtomic; ret->valueType = type; - ret->bytes = parseMemBytes(&extra, getWasmTypeSize(type)); + ret->bytes = parseMemBytes(&extra, getTypeSize(type)); size_t i = parseMemAttributes(s, &ret->offset, &ret->align, ret->bytes); ret->ptr = parseExpression(s[i]); @@ -1209,9 +1209,9 @@ Expression* SExpressionWasmBuilder::makeStore(Element& s, WasmType type, bool is return ret; } -Expression* SExpressionWasmBuilder::makeAtomicRMWOrCmpxchg(Element& s, WasmType type) { +Expression* SExpressionWasmBuilder::makeAtomicRMWOrCmpxchg(Element& s, Type type) { const char* extra = strchr(s[0]->c_str(), '.') + 11; // afer "type.atomic.rmw" - auto bytes = parseMemBytes(&extra, getWasmTypeSize(type)); + auto bytes = parseMemBytes(&extra, getTypeSize(type)); extra = strchr(extra, '.'); // after the optional '_u' and before the opcode if (!extra) throw ParseException("malformed atomic rmw instruction"); extra++; // after the '.' @@ -1219,7 +1219,7 @@ Expression* SExpressionWasmBuilder::makeAtomicRMWOrCmpxchg(Element& s, WasmType return makeAtomicRMW(s, type, bytes, extra); } -Expression* SExpressionWasmBuilder::makeAtomicRMW(Element& s, WasmType type, uint8_t bytes, const char* extra) { +Expression* SExpressionWasmBuilder::makeAtomicRMW(Element& s, Type type, uint8_t bytes, const char* extra) { auto ret = allocator.alloc<AtomicRMW>(); ret->type = type; ret->bytes = bytes; @@ -1239,7 +1239,7 @@ Expression* SExpressionWasmBuilder::makeAtomicRMW(Element& s, WasmType type, uin return ret; } -Expression* SExpressionWasmBuilder::makeAtomicCmpxchg(Element& s, WasmType type, uint8_t bytes, const char* extra) { +Expression* SExpressionWasmBuilder::makeAtomicCmpxchg(Element& s, Type type, uint8_t bytes, const char* extra) { auto ret = allocator.alloc<AtomicCmpxchg>(); ret->type = type; ret->bytes = bytes; @@ -1253,7 +1253,7 @@ Expression* SExpressionWasmBuilder::makeAtomicCmpxchg(Element& s, WasmType type, return ret; } -Expression* SExpressionWasmBuilder::makeAtomicWait(Element& s, WasmType type) { +Expression* SExpressionWasmBuilder::makeAtomicWait(Element& s, Type type) { auto ret = allocator.alloc<AtomicWait>(); ret->type = i32; ret->expectedType = type; @@ -1285,7 +1285,7 @@ Expression* SExpressionWasmBuilder::makeIf(Element& s) { } auto label = nameMapper.pushLabelName(sName); // if signature - WasmType type = parseOptionalResultType(s, i); + Type type = parseOptionalResultType(s, i); ret->condition = parseExpression(s[i++]); ret->ifTrue = parseExpression(*s[i++]); if (i < s.size()) { @@ -1305,7 +1305,7 @@ Expression* SExpressionWasmBuilder::makeIf(Element& s) { } -Expression* SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, WasmType type) { +Expression* SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, Type type) { Index stopAt = -1; if (s.size() == i) return allocator.alloc<Nop>(); if (s.size() == i+1) return parseExpression(s[i]); @@ -1320,14 +1320,14 @@ Expression* SExpressionWasmBuilder::makeMaybeBlock(Element& s, size_t i, WasmTyp return ret; } -WasmType SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) { +Type SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) { if (s.size() == i) return none; // TODO(sbc): Remove support for old result syntax (bare streing) once the // spec tests are updated. if (s[i]->isStr()) - return stringToWasmType(s[i++]->str()); + return stringToType(s[i++]->str()); Element& params = *s[i]; IString id = params[0]->str(); @@ -1335,7 +1335,7 @@ WasmType SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) { return none; i++; - return stringToWasmType(params[1]->str()); + return stringToType(params[1]->str()); } Expression* SExpressionWasmBuilder::makeLoop(Element& s) { @@ -1725,10 +1725,10 @@ void SExpressionWasmBuilder::parseImport(Element& s) { IString id = params[0]->str(); if (id == PARAM) { for (size_t k = 1; k < params.size(); k++) { - type->params.push_back(stringToWasmType(params[k]->str())); + type->params.push_back(stringToType(params[k]->str())); } } else if (id == RESULT) { - type->result = stringToWasmType(params[1]->str()); + type->result = stringToType(params[1]->str()); } else if (id == TYPE) { IString name = params[1]->str(); if (!wasm.getFunctionTypeOrNull(name)) throw ParseException("bad function type for import"); @@ -1739,17 +1739,17 @@ void SExpressionWasmBuilder::parseImport(Element& s) { if (inner.size() > j+1) { Element& result = *inner[j+1]; if (result[0]->str() != RESULT) throw ParseException("expected result"); - type->result = stringToWasmType(result[1]->str()); + type->result = stringToType(result[1]->str()); } } im->functionType = ensureFunctionType(getSig(type.get()), &wasm)->name; } else if (im->kind == ExternalKind::Global) { if (inner[j]->isStr()) { - im->globalType = stringToWasmType(inner[j]->str()); + im->globalType = stringToType(inner[j]->str()); } else { auto& inner2 = *inner[j]; if (inner2[0]->str() != MUT) throw ParseException("expected mut"); - im->globalType = stringToWasmType(inner2[1]->str()); + im->globalType = stringToType(inner2[1]->str()); throw ParseException("cannot import a mutable global", s.line, s.col); } } else if (im->kind == ExternalKind::Table) { @@ -1779,7 +1779,7 @@ void SExpressionWasmBuilder::parseImport(Element& s) { void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { std::unique_ptr<Global> global = make_unique<Global>(); size_t i = 1; - if (s[i]->dollared() && !(s[i]->isStr() && isWasmType(s[i]->str()))) { + if (s[i]->dollared() && !(s[i]->isStr() && isType(s[i]->str()))) { global->name = s[i++]->str(); } else { global->name = Name::fromInt(globalCounter); @@ -1787,7 +1787,7 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { globalCounter++; globalNames.push_back(global->name); bool mutable_ = false; - WasmType type = none; + Type type = none; bool exported = false; Name importModule, importBase; while (i < s.size() && s[i]->isList()) { @@ -1807,7 +1807,7 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { i++; } else if (inner[0]->str() == MUT) { mutable_ = true; - type = stringToWasmType(inner[1]->str()); + type = stringToType(inner[1]->str()); i++; } else { break; @@ -1815,7 +1815,7 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { } if (exported && mutable_) throw ParseException("cannot export a mutable global", s.line, s.col); if (type == none) { - type = stringToWasmType(s[i++]->str()); + type = stringToType(s[i++]->str()); } if (importModule.is()) { // this is an import, actually @@ -1949,11 +1949,11 @@ void SExpressionWasmBuilder::parseType(Element& s) { Element& curr = *func[k]; if (curr[0]->str() == PARAM) { for (size_t j = 1; j < curr.size(); j++) { - type->params.push_back(stringToWasmType(curr[j]->str())); + type->params.push_back(stringToType(curr[j]->str())); } } else if (curr[0]->str() == RESULT) { if (curr.size() > 2) throw ParseException("invalid result arity", curr.line, curr.col); - type->result = stringToWasmType(curr[1]->str()); + type->result = stringToType(curr[1]->str()); } } if (!type->name.is()) { diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 1e48ce525..4b159b6e2 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -21,30 +21,30 @@ namespace wasm { -const char* printWasmType(WasmType type) { +const char* printType(Type type) { switch (type) { - case WasmType::none: return "none"; - case WasmType::i32: return "i32"; - case WasmType::i64: return "i64"; - case WasmType::f32: return "f32"; - case WasmType::f64: return "f64"; - case WasmType::unreachable: return "unreachable"; + case Type::none: return "none"; + case Type::i32: return "i32"; + case Type::i64: return "i64"; + case Type::f32: return "f32"; + case Type::f64: return "f64"; + case Type::unreachable: return "unreachable"; default: WASM_UNREACHABLE(); } } -unsigned getWasmTypeSize(WasmType type) { +unsigned getTypeSize(Type type) { switch (type) { - case WasmType::none: abort(); - case WasmType::i32: return 4; - case WasmType::i64: return 8; - case WasmType::f32: return 4; - case WasmType::f64: return 8; + case Type::none: abort(); + case Type::i32: return 4; + case Type::i64: return 8; + case Type::f32: return 4; + case Type::f64: return 8; default: WASM_UNREACHABLE(); } } -bool isWasmTypeFloat(WasmType type) { +bool isTypeFloat(Type type) { switch (type) { case f32: case f64: return true; @@ -52,18 +52,18 @@ bool isWasmTypeFloat(WasmType type) { } } -WasmType getWasmType(unsigned size, bool float_) { - if (size < 4) return WasmType::i32; - if (size == 4) return float_ ? WasmType::f32 : WasmType::i32; - if (size == 8) return float_ ? WasmType::f64 : WasmType::i64; +Type getType(unsigned size, bool float_) { + if (size < 4) return Type::i32; + if (size == 4) return float_ ? Type::f32 : Type::i32; + if (size == 8) return float_ ? Type::f64 : Type::i64; abort(); } -WasmType getReachableWasmType(WasmType a, WasmType b) { +Type getReachableType(Type a, Type b) { return a != unreachable ? a : b; } -bool isConcreteWasmType(WasmType type) { +bool isConcreteType(Type type) { return type != none && type != unreachable; } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 26b8c66b6..84dd43b20 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -153,7 +153,7 @@ struct ValidationInfo { return true; } - void shouldBeIntOrUnreachable(WasmType ty, Expression* curr, const char* text, Function* func = nullptr) { + void shouldBeIntOrUnreachable(Type ty, Expression* curr, const char* text, Function* func = nullptr) { switch (ty) { case i32: case i64: @@ -176,16 +176,16 @@ struct FunctionValidator : public WalkerPass<PostWalker<FunctionValidator>> { FunctionValidator(ValidationInfo* info) : info(*info) {} struct BreakInfo { - WasmType type; + Type type; Index arity; BreakInfo() {} - BreakInfo(WasmType type, Index arity) : type(type), arity(arity) {} + BreakInfo(Type type, Index arity) : type(type), arity(arity) {} }; std::map<Name, Expression*> breakTargets; std::map<Expression*, BreakInfo> breakInfos; - WasmType returnType = unreachable; // type used in returns + Type returnType = unreachable; // type used in returns std::set<Name> labelNames; // Binaryen IR requires that label names must be unique - IR generators must ensure that @@ -274,13 +274,13 @@ private: return info.shouldBeUnequal(left, right, curr, text, getFunction()); } - void shouldBeIntOrUnreachable(WasmType ty, Expression* curr, const char* text) { + void shouldBeIntOrUnreachable(Type ty, Expression* curr, const char* text) { return info.shouldBeIntOrUnreachable(ty, curr, text, getFunction()); } - void validateAlignment(size_t align, WasmType type, Index bytes, bool isAtomic, + void validateAlignment(size_t align, Type type, Index bytes, bool isAtomic, Expression* curr); - void validateMemBytes(uint8_t bytes, WasmType type, Expression* curr); + void validateMemBytes(uint8_t bytes, Type type, Expression* curr); }; void FunctionValidator::noteLabelName(Name name) { @@ -295,22 +295,22 @@ void FunctionValidator::visitBlock(Block *curr) { noteLabelName(curr->name); if (breakInfos.count(curr) > 0) { auto& info = breakInfos[curr]; - if (isConcreteWasmType(curr->type)) { + if (isConcreteType(curr->type)) { shouldBeTrue(info.arity != 0, curr, "break arities must be > 0 if block has a value"); } else { shouldBeTrue(info.arity == 0, curr, "break arities must be 0 if block has no value"); } // none or unreachable means a poison value that we should ignore - if consumed, it will error - if (isConcreteWasmType(info.type) && isConcreteWasmType(curr->type)) { + if (isConcreteType(info.type) && isConcreteType(curr->type)) { shouldBeEqual(curr->type, info.type, curr, "block+breaks must have right type if breaks return a value"); } - if (isConcreteWasmType(curr->type) && info.arity && info.type != unreachable) { + if (isConcreteType(curr->type) && info.arity && info.type != unreachable) { shouldBeEqual(curr->type, info.type, curr, "block+breaks must have right type if breaks have arity"); } shouldBeTrue(info.arity != Index(-1), curr, "break arities must match"); if (curr->list.size() > 0) { auto last = curr->list.back()->type; - if (isConcreteWasmType(last) && info.type != unreachable) { + if (isConcreteType(last) && info.type != unreachable) { shouldBeEqual(last, info.type, curr, "block+breaks must have right type if block ends with a reachable value"); } if (last == none) { @@ -322,24 +322,24 @@ void FunctionValidator::visitBlock(Block *curr) { } if (curr->list.size() > 1) { for (Index i = 0; i < curr->list.size() - 1; i++) { - if (!shouldBeTrue(!isConcreteWasmType(curr->list[i]->type), curr, "non-final block elements returning a value must be drop()ed (binaryen's autodrop option might help you)") && !info.quiet) { + if (!shouldBeTrue(!isConcreteType(curr->list[i]->type), curr, "non-final block elements returning a value must be drop()ed (binaryen's autodrop option might help you)") && !info.quiet) { getStream() << "(on index " << i << ":\n" << curr->list[i] << "\n), type: " << curr->list[i]->type << "\n"; } } } if (curr->list.size() > 0) { auto backType = curr->list.back()->type; - if (!isConcreteWasmType(curr->type)) { - shouldBeFalse(isConcreteWasmType(backType), curr, "if block is not returning a value, final element should not flow out a value"); + if (!isConcreteType(curr->type)) { + shouldBeFalse(isConcreteType(backType), curr, "if block is not returning a value, final element should not flow out a value"); } else { - if (isConcreteWasmType(backType)) { + if (isConcreteType(backType)) { shouldBeEqual(curr->type, backType, curr, "block with value and last element with value must match types"); } else { shouldBeUnequal(backType, none, curr, "block with value must not have last element that is none"); } } } - if (isConcreteWasmType(curr->type)) { + if (isConcreteType(curr->type)) { shouldBeTrue(curr->list.size() > 0, curr, "block with a value must not be empty"); } } @@ -354,14 +354,14 @@ void FunctionValidator::visitLoop(Loop *curr) { } } if (curr->type == none) { - shouldBeFalse(isConcreteWasmType(curr->body->type), curr, "bad body for a loop that has no value"); + shouldBeFalse(isConcreteType(curr->body->type), curr, "bad body for a loop that has no value"); } } void FunctionValidator::visitIf(If *curr) { shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "if condition must be valid"); if (!curr->ifFalse) { - shouldBeFalse(isConcreteWasmType(curr->ifTrue->type), curr, "if without else must not return a value in body"); + shouldBeFalse(isConcreteType(curr->ifTrue->type), curr, "if without else must not return a value in body"); if (curr->condition->type != unreachable) { shouldBeEqual(curr->type, none, curr, "if without else and reachable condition must be none"); } @@ -375,11 +375,11 @@ void FunctionValidator::visitIf(If *curr) { shouldBeEqual(curr->ifFalse->type, unreachable, curr, "unreachable if-else must have unreachable false"); } } - if (isConcreteWasmType(curr->ifTrue->type)) { + if (isConcreteType(curr->ifTrue->type)) { shouldBeEqual(curr->type, curr->ifTrue->type, curr, "if type must match concrete ifTrue"); shouldBeEqualOrFirstIsUnreachable(curr->ifFalse->type, curr->ifTrue->type, curr, "other arm must match concrete ifTrue"); } - if (isConcreteWasmType(curr->ifFalse->type)) { + if (isConcreteType(curr->ifFalse->type)) { shouldBeEqual(curr->type, curr->ifFalse->type, curr, "if type must match concrete ifFalse"); shouldBeEqualOrFirstIsUnreachable(curr->ifTrue->type, curr->ifFalse->type, curr, "other arm must match concrete ifFalse"); } @@ -387,7 +387,7 @@ void FunctionValidator::visitIf(If *curr) { } void FunctionValidator::noteBreak(Name name, Expression* value, Expression* curr) { - WasmType valueType = none; + Type valueType = none; Index arity = 0; if (value) { valueType = value->type; @@ -473,7 +473,7 @@ void FunctionValidator::visitCallIndirect(CallIndirect *curr) { void FunctionValidator::visitGetLocal(GetLocal* curr) { shouldBeTrue(curr->index < getFunction()->getNumLocals(), curr, "get_local index must be small enough"); - shouldBeTrue(isConcreteWasmType(curr->type), curr, "get_local must have a valid type - check what you provided when you constructed the node"); + shouldBeTrue(isConcreteType(curr->type), curr, "get_local must have a valid type - check what you provided when you constructed the node"); } void FunctionValidator::visitSetLocal(SetLocal *curr) { @@ -558,7 +558,7 @@ void FunctionValidator::visitAtomicWake(AtomicWake* curr) { shouldBeEqualOrFirstIsUnreachable(curr->wakeCount->type, i32, curr, "AtomicWake wakeCount type must be i32"); } -void FunctionValidator::validateMemBytes(uint8_t bytes, WasmType type, Expression* curr) { +void FunctionValidator::validateMemBytes(uint8_t bytes, Type type, Expression* curr) { switch (bytes) { case 1: case 2: @@ -567,7 +567,7 @@ void FunctionValidator::validateMemBytes(uint8_t bytes, WasmType type, Expressio // if we have a concrete type for the load, then we know the size of the mem operation and // can validate it if (type != unreachable) { - shouldBeEqual(getWasmTypeSize(type), 8U, curr, "8-byte mem operations are only allowed with 8-byte wasm types"); + shouldBeEqual(getTypeSize(type), 8U, curr, "8-byte mem operations are only allowed with 8-byte wasm types"); } break; } @@ -764,7 +764,7 @@ void FunctionValidator::visitSelect(Select* curr) { } void FunctionValidator::visitDrop(Drop* curr) { - shouldBeTrue(isConcreteWasmType(curr->value->type) || curr->value->type == unreachable, curr, "can only drop a valid value"); + shouldBeTrue(isConcreteType(curr->value->type) || curr->value->type == unreachable, curr, "can only drop a valid value"); } void FunctionValidator::visitReturn(Return* curr) { @@ -840,7 +840,7 @@ static bool checkOffset(Expression* curr, Address add, Address max) { return offset + add <= max; } -void FunctionValidator::validateAlignment(size_t align, WasmType type, Index bytes, +void FunctionValidator::validateAlignment(size_t align, Type type, Index bytes, bool isAtomic, Expression* curr) { if (isAtomic) { shouldBeEqual(align, (size_t)bytes, curr, "atomic accesses must have natural alignment"); @@ -891,9 +891,9 @@ static void validateBinaryenIR(Module& wasm, ValidationInfo& info) { // // The block has an added type, not derived from the ast itself, so it is // ok for it to be either i32 or unreachable. - if (!(isConcreteWasmType(oldType) && newType == unreachable)) { + if (!(isConcreteType(oldType) && newType == unreachable)) { std::ostringstream ss; - ss << "stale type found in " << (getFunction() ? getFunction()->name : Name("(global scope)")) << " on " << curr << "\n(marked as " << printWasmType(oldType) << ", should be " << printWasmType(newType) << ")\n"; + ss << "stale type found in " << (getFunction() ? getFunction()->name : Name("(global scope)")) << " on " << curr << "\n(marked as " << printType(oldType) << ", should be " << printType(newType) << ")\n"; info.fail(ss.str(), curr, getFunction()); } curr->type = oldType; @@ -912,7 +912,7 @@ static void validateImports(Module& module, ValidationInfo& info) { if (info.validateWeb) { auto* functionType = module.getFunctionType(curr->functionType); info.shouldBeUnequal(functionType->result, i64, curr->name, "Imported function must not have i64 return type"); - for (WasmType param : functionType->params) { + for (Type param : functionType->params) { info.shouldBeUnequal(param, i64, curr->name, "Imported function must not have i64 parameters"); } } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 32a633926..cf847d5aa 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -107,7 +107,7 @@ const char* getExpressionName(Expression* curr) { struct TypeSeeker : public PostWalker<TypeSeeker> { Expression* target; // look for this one Name targetName; - std::vector<WasmType> types; + std::vector<Type> types; TypeSeeker(Expression* target, Name targetName) : target(target), targetName(targetName) { @@ -149,8 +149,8 @@ struct TypeSeeker : public PostWalker<TypeSeeker> { } }; -static WasmType mergeTypes(std::vector<WasmType>& types) { - WasmType type = unreachable; +static Type mergeTypes(std::vector<Type>& types) { + Type type = unreachable; for (auto other : types) { // once none, stop. it then indicates a poison value, that must not be consumed // and ignore unreachable @@ -177,7 +177,7 @@ static void handleUnreachable(Block* block) { // if we are concrete, stop - even an unreachable child // won't change that (since we have a break with a value, // or the final child flows out a value) - if (isConcreteWasmType(block->type)) return; + if (isConcreteType(block->type)) return; // look for an unreachable child for (auto* child : block->list) { if (child->type == unreachable) { @@ -190,7 +190,7 @@ static void handleUnreachable(Block* block) { } } -void Block::finalize(WasmType type_) { +void Block::finalize(Type type_) { type = type_; if (type == none && list.size() > 0) { handleUnreachable(this); @@ -209,7 +209,7 @@ void Block::finalize() { // (return) // (i32.const 10) // ) - if (isConcreteWasmType(type)) return; + if (isConcreteType(type)) return; // if we are unreachable, we are done if (type == unreachable) return; // we may still be unreachable if we have an unreachable @@ -231,7 +231,7 @@ void Block::finalize() { handleUnreachable(this); } -void If::finalize(WasmType type_) { +void If::finalize(Type type_) { type = type_; if (type == none && (condition->type == unreachable || (ifFalse && ifTrue->type == unreachable && ifFalse->type == unreachable))) { type = unreachable; @@ -242,9 +242,9 @@ void If::finalize() { if (ifFalse) { if (ifTrue->type == ifFalse->type) { type = ifTrue->type; - } else if (isConcreteWasmType(ifTrue->type) && ifFalse->type == unreachable) { + } else if (isConcreteType(ifTrue->type) && ifFalse->type == unreachable) { type = ifTrue->type; - } else if (isConcreteWasmType(ifFalse->type) && ifTrue->type == unreachable) { + } else if (isConcreteType(ifFalse->type) && ifTrue->type == unreachable) { type = ifFalse->type; } else { type = none; @@ -265,7 +265,7 @@ void If::finalize() { } } -void Loop::finalize(WasmType type_) { +void Loop::finalize(Type type_) { type = type_; if (type == none && body->type == unreachable) { type = unreachable; @@ -613,7 +613,7 @@ Index Function::getVarIndexBase() { return params.size(); } -WasmType Function::getLocalType(Index index) { +Type Function::getLocalType(Index index) { if (isParam(index)) { return params[index]; } else if (isVar(index)) { |