diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/literal.cpp | 42 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 32 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 4 |
6 files changed, 86 insertions, 16 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 39a4cea3c..4a89b5cd1 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -70,7 +70,10 @@ Literal::Literal(const Literal& other) : type(other.type) { break; case Type::externref: case Type::anyref: + case Type::eqref: break; // null + case Type::i31ref: + WASM_UNREACHABLE("TODO: i31ref"); case Type::funcref: case Type::exnref: case Type::unreachable: @@ -223,10 +226,11 @@ void Literal::getBits(uint8_t (&buf)[16]) const { case Type::externref: case Type::exnref: case Type::anyref: - if (isNull()) { - break; - } - // falls through + case Type::eqref: + assert(isNull() && "unexpected non-null reference type literal"); + break; + case Type::i31ref: + WASM_UNREACHABLE("TODO: i31ref"); case Type::none: case Type::unreachable: WASM_UNREACHABLE("invalid type"); @@ -379,6 +383,10 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { o << "funcref(" << literal.getFunc() << ")"; } break; + case Type::externref: + assert(literal.isNull() && "unexpected non-null externref literal"); + o << "externref(null)"; + break; case Type::exnref: if (literal.isNull()) { o << "exnref(null)"; @@ -387,13 +395,15 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { } break; case Type::anyref: - assert(literal.isNull() && "TODO: non-null anyref values"); + assert(literal.isNull() && "unexpected non-null anyref literal"); o << "anyref(null)"; break; - case Type::externref: - assert(literal.isNull() && "TODO: non-null externref values"); - o << "externref(null)"; + case Type::eqref: + assert(literal.isNull() && "unexpected non-null eqref literal"); + o << "eqref(null)"; break; + case Type::i31ref: + WASM_UNREACHABLE("TODO: i31ref"); case Type::unreachable: WASM_UNREACHABLE("invalid type"); } @@ -619,6 +629,8 @@ Literal Literal::eqz() const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -641,6 +653,8 @@ Literal Literal::neg() const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -663,6 +677,8 @@ Literal Literal::abs() const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -768,6 +784,8 @@ Literal Literal::add(const Literal& other) const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -790,6 +808,8 @@ Literal Literal::sub(const Literal& other) const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -908,6 +928,8 @@ Literal Literal::mul(const Literal& other) const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -1154,6 +1176,8 @@ Literal Literal::eq(const Literal& other) const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -1176,6 +1200,8 @@ Literal Literal::ne(const Literal& other) const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 18a66fb2c..a6299c892 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1206,10 +1206,14 @@ Type WasmBinaryBuilder::getType() { return Type::exnref; case BinaryConsts::EncodedType::anyref: return Type::anyref; + case BinaryConsts::EncodedType::eqref: + return Type::eqref; + case BinaryConsts::EncodedType::i31ref: + return Type::i31ref; default: throwError("invalid wasm type: " + std::to_string(type)); } - WASM_UNREACHABLE("unexpeced type"); + WASM_UNREACHABLE("unexpected type"); } HeapType WasmBinaryBuilder::getHeapType() { @@ -1230,10 +1234,14 @@ HeapType WasmBinaryBuilder::getHeapType() { return HeapType::ExnKind; case BinaryConsts::EncodedHeapType::any: return HeapType::AnyKind; + case BinaryConsts::EncodedHeapType::eq: + return HeapType::EqKind; + case BinaryConsts::EncodedHeapType::i31: + return HeapType::I31Kind; default: throwError("invalid wasm heap type: " + std::to_string(type)); } - WASM_UNREACHABLE("unexpeced type"); + WASM_UNREACHABLE("unexpected type"); } Type WasmBinaryBuilder::getConcreteType() { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 8bbcc9ac0..2aa60979f 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -875,6 +875,12 @@ Type SExpressionWasmBuilder::stringToType(const char* str, if (strncmp(str, "anyref", 6) == 0 && (prefix || str[6] == 0)) { return Type::anyref; } + if (strncmp(str, "eqref", 5) == 0 && (prefix || str[5] == 0)) { + return Type::eqref; + } + if (strncmp(str, "i31ref", 6) == 0 && (prefix || str[6] == 0)) { + return Type::i31ref; + } if (allowError) { return Type::none; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 30816546a..66f9e02dd 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -192,6 +192,8 @@ void BinaryInstWriter::visitLoad(Load* curr) { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: WASM_UNREACHABLE("unexpected type"); } @@ -294,6 +296,8 @@ void BinaryInstWriter::visitStore(Store* curr) { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); @@ -697,6 +701,8 @@ void BinaryInstWriter::visitConst(Const* curr) { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: WASM_UNREACHABLE("unexpected type"); diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index d88b7b027..cf68d92e9 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -260,9 +260,10 @@ std::unordered_map<TypeInfo, uintptr_t> indices = { {TypeInfo(HeapType(HeapType::ExnKind), true), Type::exnref}, {TypeInfo({Type::anyref}), Type::anyref}, {TypeInfo(HeapType(HeapType::AnyKind), true), Type::anyref}, - // TODO (GC): Add canonical ids - // * `(ref null eq) == eqref` - // * `(ref i31) == i31ref` + {TypeInfo({Type::eqref}), Type::eqref}, + {TypeInfo(HeapType(HeapType::EqKind), true), Type::eqref}, + {TypeInfo({Type::i31ref}), Type::i31ref}, + {TypeInfo(HeapType(HeapType::I31Kind), false), Type::i31ref}, }; } // anonymous namespace @@ -341,7 +342,7 @@ bool Type::isTuple() const { bool Type::isRef() const { if (isBasic()) { - return id >= funcref && id <= anyref; + return id >= funcref && id <= i31ref; } else { return getTypeInfo(*this)->isRef(); } @@ -367,7 +368,7 @@ bool Type::isException() const { bool Type::isNullable() const { if (isBasic()) { - return id >= funcref && id <= anyref; + return id >= funcref && id <= eqref; // except i31ref } else { return getTypeInfo(*this)->isNullable(); } @@ -409,6 +410,8 @@ unsigned Type::getByteSize() const { case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: case Type::unreachable: break; @@ -454,6 +457,8 @@ FeatureSet Type::getFeatures() const { case Type::exnref: return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling; case Type::anyref: + case Type::eqref: + case Type::i31ref: return FeatureSet::ReferenceTypes | FeatureSet::GC; default: return FeatureSet::MVP; @@ -484,6 +489,10 @@ HeapType Type::getHeapType() const { return HeapType::ExnKind; case anyref: return HeapType::AnyKind; + case eqref: + return HeapType::EqKind; + case i31ref: + return HeapType::I31Kind; default: break; } @@ -512,7 +521,8 @@ bool Type::isSubType(Type left, Type right) { return true; } if (left.isRef() && right.isRef()) { - return right == Type::anyref; + return right == Type::anyref || + (left == Type::i31ref && right == Type::eqref); } if (left.isTuple() && right.isTuple()) { if (left.size() != right.size()) { @@ -543,6 +553,10 @@ Type Type::getLeastUpperBound(Type a, Type b) { } if (a.isRef()) { if (b.isRef()) { + if ((a == Type::i31ref && b == Type::eqref) || + (a == Type::eqref && b == Type::i31ref)) { + return Type::eqref; + } // The LUB of two different reference types is anyref, which may or may // not be a valid type depending on whether the anyref feature is enabled. // When anyref is disabled, it is possible for the finalization of invalid @@ -754,6 +768,12 @@ std::ostream& operator<<(std::ostream& os, Type type) { case Type::anyref: os << "anyref"; break; + case Type::eqref: + os << "eqref"; + break; + case Type::i31ref: + os << "i31ref"; + break; } } else { os << *getTypeInfo(type); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 505753c88..16ba60d72 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1396,6 +1396,8 @@ void FunctionValidator::validateMemBytes(uint8_t bytes, case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: WASM_UNREACHABLE("unexpected type"); } @@ -2204,6 +2206,8 @@ void FunctionValidator::validateAlignment( case Type::externref: case Type::exnref: case Type::anyref: + case Type::eqref: + case Type::i31ref: case Type::none: WASM_UNREACHABLE("invalid type"); } |