diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-c.cpp | 4 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 7 | ||||
-rw-r--r-- | src/tools/fuzzing/heap-types.cpp | 6 | ||||
-rw-r--r-- | src/wasm-binary.h | 4 | ||||
-rw-r--r-- | src/wasm-type.h | 6 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 40 |
9 files changed, 103 insertions, 6 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index a34876078..93e3f609b 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -86,6 +86,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { case HeapType::any: case HeapType::eq: case HeapType::func: + case HeapType::cont: case HeapType::struct_: case HeapType::array: case HeapType::exn: @@ -98,6 +99,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: // Null. return ret; @@ -141,6 +143,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { WASM_UNREACHABLE("TODO: extern literals"); case HeapType::eq: case HeapType::func: + case HeapType::cont: case HeapType::struct_: case HeapType::array: case HeapType::exn: @@ -153,6 +156,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) { case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: assert(type.isNullable()); return Literal::makeNull(heapType); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index e20333500..cbf8f2f4d 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -2525,6 +2525,9 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { case HeapType::func: { return makeRefFuncConst(type); } + case HeapType::cont: { + WASM_UNREACHABLE("not implemented"); + } case HeapType::any: { // Choose a subtype we can materialize a constant for. We cannot // materialize non-nullable refs to func or i31 in global contexts. @@ -2652,6 +2655,7 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: { auto null = builder.makeRefNull(heapType); if (!type.isNullable()) { @@ -4076,6 +4080,8 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) { return pick(FeatureOptions<HeapType>() .add(FeatureSet::ReferenceTypes, HeapType::func) .add(FeatureSet::GC, HeapType::nofunc)); + case HeapType::cont: + return pick(HeapType::cont, HeapType::nocont); case HeapType::ext: return pick(FeatureOptions<HeapType>() .add(FeatureSet::ReferenceTypes, HeapType::ext) @@ -4116,6 +4122,7 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) { case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: break; } diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 33a92b796..3d0d29153 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -380,6 +380,8 @@ struct HeapTypeGeneratorImpl { switch (type.getBasic()) { case HeapType::func: return pickSubFunc(); + case HeapType::cont: + WASM_UNREACHABLE("not implemented"); case HeapType::any: return pickSubAny(); case HeapType::eq: @@ -399,6 +401,7 @@ struct HeapTypeGeneratorImpl { case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: return type; } @@ -442,6 +445,7 @@ struct HeapTypeGeneratorImpl { case HeapType::ext: case HeapType::func: case HeapType::exn: + case HeapType::cont: case HeapType::any: break; case HeapType::eq: @@ -470,6 +474,8 @@ struct HeapTypeGeneratorImpl { return pickSubAny(); case HeapType::nofunc: return pickSubFunc(); + case HeapType::nocont: + WASM_UNREACHABLE("not implemented"); case HeapType::noext: candidates.push_back(HeapType::ext); break; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index f8463f3b1..4f0796601 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -372,6 +372,8 @@ enum EncodedType { eqref = -0x13, // 0x6d nonnullable = -0x1c, // 0x64 nullable = -0x1d, // 0x63 + contref = -0x18, // 0x68 + nullcontref = -0x0b, // 0x75 // exception handling exnref = -0x17, // 0x69 nullexnref = -0xc, // 0x74 @@ -403,6 +405,8 @@ enum EncodedHeapType { eq = -0x13, // 0x6d exn = -0x17, // 0x69 noexn = -0xc, // 0x74 + cont = -0x18, // 0x68 + nocont = -0x0b, // 0x75 i31 = -0x14, // 0x6c struct_ = -0x15, // 0x6b array = -0x16, // 0x6a diff --git a/src/wasm-type.h b/src/wasm-type.h index 5c47f4051..b18eaa6db 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -321,6 +321,7 @@ public: enum BasicHeapType : uint32_t { ext, func, + cont, any, eq, i31, @@ -334,6 +335,7 @@ public: none, noext, nofunc, + nocont, noexn, }; static constexpr BasicHeapType _last_basic_type = noexn; @@ -367,6 +369,10 @@ public: bool isFunction() const; bool isData() const; bool isSignature() const; + // Indicates whether the given type was defined to be of the form + // `(cont $ft)`. Returns false for `cont`, the top type of the continuation + // type hierarchy (and all other types). In other words, this is analogous to + // `isSignature`, but for continuation types. bool isContinuation() const; bool isStruct() const; bool isArray() const; diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 887c777ec..48ade5447 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -138,10 +138,12 @@ Literal::Literal(const Literal& other) : type(other.type) { case HeapType::noext: case HeapType::nofunc: case HeapType::noexn: + case HeapType::nocont: WASM_UNREACHABLE("null literals should already have been handled"); case HeapType::any: case HeapType::eq: case HeapType::func: + case HeapType::cont: case HeapType::struct_: case HeapType::array: case HeapType::exn: @@ -622,6 +624,9 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { case HeapType::noexn: o << "nullexnref"; break; + case HeapType::nocont: + o << "nullcontref"; + break; case HeapType::ext: o << "externref"; break; @@ -631,6 +636,7 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { case HeapType::any: case HeapType::eq: case HeapType::func: + case HeapType::cont: case HeapType::struct_: case HeapType::array: WASM_UNREACHABLE("invalid type"); diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 28a630c4a..869b44f2c 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1500,6 +1500,9 @@ void WasmBinaryWriter::writeType(Type type) { case HeapType::func: o << S32LEB(BinaryConsts::EncodedType::funcref); return; + case HeapType::cont: + o << S32LEB(BinaryConsts::EncodedType::contref); + return; case HeapType::eq: o << S32LEB(BinaryConsts::EncodedType::eqref); return; @@ -1539,6 +1542,9 @@ void WasmBinaryWriter::writeType(Type type) { case HeapType::noexn: o << S32LEB(BinaryConsts::EncodedType::nullexnref); return; + case HeapType::nocont: + o << S32LEB(BinaryConsts::EncodedType::nullcontref); + return; } } if (type.isNullable()) { @@ -1612,6 +1618,9 @@ void WasmBinaryWriter::writeHeapType(HeapType type) { case HeapType::func: ret = BinaryConsts::EncodedHeapType::func; break; + case HeapType::cont: + ret = BinaryConsts::EncodedHeapType::cont; + break; case HeapType::any: ret = BinaryConsts::EncodedHeapType::any; break; @@ -1654,6 +1663,9 @@ void WasmBinaryWriter::writeHeapType(HeapType type) { case HeapType::noexn: ret = BinaryConsts::EncodedHeapType::noexn; break; + case HeapType::nocont: + ret = BinaryConsts::EncodedHeapType::nocont; + break; } o << S64LEB(ret); // TODO: Actually s33 } @@ -1986,6 +1998,9 @@ bool WasmBinaryReader::getBasicType(int32_t code, Type& out) { case BinaryConsts::EncodedType::funcref: out = Type(HeapType::func, Nullable); return true; + case BinaryConsts::EncodedType::contref: + out = Type(HeapType::cont, Nullable); + return true; case BinaryConsts::EncodedType::externref: out = Type(HeapType::ext, Nullable); return true; @@ -2031,6 +2046,9 @@ bool WasmBinaryReader::getBasicType(int32_t code, Type& out) { case BinaryConsts::EncodedType::nullexnref: out = Type(HeapType::noexn, Nullable); return true; + case BinaryConsts::EncodedType::nullcontref: + out = Type(HeapType::nocont, Nullable); + return true; default: return false; } @@ -2041,6 +2059,9 @@ bool WasmBinaryReader::getBasicHeapType(int64_t code, HeapType& out) { case BinaryConsts::EncodedHeapType::func: out = HeapType::func; return true; + case BinaryConsts::EncodedHeapType::cont: + out = HeapType::func; + return true; case BinaryConsts::EncodedHeapType::ext: out = HeapType::ext; return true; @@ -2086,6 +2107,9 @@ bool WasmBinaryReader::getBasicHeapType(int64_t code, HeapType& out) { case BinaryConsts::EncodedHeapType::noexn: out = HeapType::noexn; return true; + case BinaryConsts::EncodedHeapType::nocont: + out = HeapType::nocont; + return true; default: return false; } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index c7cedfdbd..5ac36fda7 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1257,6 +1257,9 @@ Type SExpressionWasmBuilder::stringToType(std::string_view str, if (str.substr(0, 7) == "funcref" && (prefix || str.size() == 7)) { return Type(HeapType::func, Nullable); } + if (str.substr(0, 7) == "contref" && (prefix || str.size() == 7)) { + return Type(HeapType::cont, Nullable); + } if (str.substr(0, 9) == "externref" && (prefix || str.size() == 9)) { return Type(HeapType::ext, Nullable); } @@ -1302,6 +1305,9 @@ Type SExpressionWasmBuilder::stringToType(std::string_view str, if (str.substr(0, 10) == "nullexnref" && (prefix || str.size() == 10)) { return Type(HeapType::noexn, Nullable); } + if (str.substr(0, 11) == "nullcontref" && (prefix || str.size() == 11)) { + return Type(HeapType::nocont, Nullable); + } if (allowError) { return Type::none; } @@ -1314,6 +1320,9 @@ HeapType SExpressionWasmBuilder::stringToHeapType(std::string_view str, if (str.substr(0, 4) == "func" && (prefix || str.size() == 4)) { return HeapType::func; } + if (str.substr(0, 4) == "cont" && (prefix || str.size() == 4)) { + return HeapType::cont; + } if (str.substr(0, 2) == "eq" && (prefix || str.size() == 2)) { return HeapType::eq; } @@ -1362,6 +1371,9 @@ HeapType SExpressionWasmBuilder::stringToHeapType(std::string_view str, if (str.substr(0, 5) == "noexn" && (prefix || str.size() == 5)) { return HeapType::noexn; } + if (str.substr(0, 6) == "nocont" && (prefix || str.size() == 6)) { + return HeapType::nocont; + } throw ParseException(std::string("invalid wasm heap type: ") + std::string(str.data(), str.size())); } diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 32da64470..16ab426ad 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -442,7 +442,7 @@ HeapType::BasicHeapType getBasicHeapSupertype(HeapType type) { case HeapTypeInfo::SignatureKind: return HeapType::func; case HeapTypeInfo::ContinuationKind: - return HeapType::any; + return HeapType::cont; case HeapTypeInfo::StructKind: return HeapType::struct_; case HeapTypeInfo::ArrayKind: @@ -472,6 +472,7 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a, switch (a) { case HeapType::ext: case HeapType::func: + case HeapType::cont: case HeapType::exn: return std::nullopt; case HeapType::any: @@ -503,6 +504,7 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a, case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: // Bottom types already handled. break; @@ -930,6 +932,10 @@ FeatureSet Type::getFeatures() const { feats |= FeatureSet::ExceptionHandling | FeatureSet::ReferenceTypes; return; + case HeapType::cont: + case HeapType::nocont: + feats |= FeatureSet::TypedContinuations; + return; } } @@ -1213,6 +1219,7 @@ bool HeapType::isBottom() const { switch (getBasic()) { case ext: case func: + case cont: case any: case eq: case i31: @@ -1227,6 +1234,7 @@ bool HeapType::isBottom() const { case none: case noext: case nofunc: + case nocont: case noexn: return true; } @@ -1286,6 +1294,8 @@ std::optional<HeapType> HeapType::getSuperType() const { case noext: case func: case nofunc: + case cont: + case nocont: case any: case none: case exn: @@ -1309,7 +1319,7 @@ std::optional<HeapType> HeapType::getSuperType() const { case HeapTypeInfo::SignatureKind: return func; case HeapTypeInfo::ContinuationKind: - return any; + return cont; case HeapTypeInfo::StructKind: return struct_; case HeapTypeInfo::ArrayKind: @@ -1329,10 +1339,8 @@ size_t HeapType::getDepth() const { // implicit supertyping wrt basic types. A signature type always has one more // super, HeapType::func, etc. if (!isBasic()) { - if (isFunction()) { + if (isFunction() || isContinuation()) { depth++; - } else if (isContinuation()) { - // cont types <: any, thus nothing to add } else if (isStruct()) { // specific struct types <: struct <: eq <: any depth += 3; @@ -1345,6 +1353,7 @@ size_t HeapType::getDepth() const { switch (getBasic()) { case HeapType::ext: case HeapType::func: + case HeapType::cont: case HeapType::any: case HeapType::exn: break; @@ -1362,6 +1371,7 @@ size_t HeapType::getDepth() const { break; case HeapType::none: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noext: case HeapType::noexn: // Bottom types are infinitely deep. @@ -1378,6 +1388,8 @@ HeapType::BasicHeapType HeapType::getBottom() const { return noext; case func: return nofunc; + case cont: + return nocont; case exn: return noexn; case any: @@ -1395,6 +1407,8 @@ HeapType::BasicHeapType HeapType::getBottom() const { return noext; case nofunc: return nofunc; + case nocont: + return nocont; case noexn: return noexn; } @@ -1404,7 +1418,7 @@ HeapType::BasicHeapType HeapType::getBottom() const { case HeapTypeInfo::SignatureKind: return nofunc; case HeapTypeInfo::ContinuationKind: - return none; + return nocont; case HeapTypeInfo::StructKind: case HeapTypeInfo::ArrayKind: return none; @@ -1426,12 +1440,15 @@ HeapType::BasicHeapType HeapType::getTop() const { return any; case nofunc: return func; + case nocont: + return cont; case noext: return ext; case noexn: return exn; case ext: case func: + case cont: case any: case eq: case i31: @@ -1719,6 +1736,8 @@ bool SubTyper::isSubType(HeapType a, HeapType b) { return a.getTop() == HeapType::ext; case HeapType::func: return a.getTop() == HeapType::func; + case HeapType::cont: + return a.getTop() == HeapType::cont; case HeapType::exn: return a.getTop() == HeapType::exn; case HeapType::any: @@ -1741,6 +1760,7 @@ bool SubTyper::isSubType(HeapType a, HeapType b) { case HeapType::none: case HeapType::noext: case HeapType::nofunc: + case HeapType::nocont: case HeapType::noexn: return false; } @@ -1856,6 +1876,8 @@ std::ostream& TypePrinter::print(Type type) { return os << "externref"; case HeapType::func: return os << "funcref"; + case HeapType::cont: + return os << "contref"; case HeapType::any: return os << "anyref"; case HeapType::eq: @@ -1882,6 +1904,8 @@ std::ostream& TypePrinter::print(Type type) { return os << "nullexternref"; case HeapType::nofunc: return os << "nullfuncref"; + case HeapType::nocont: + return os << "nullcontref"; case HeapType::noexn: return os << "nullexnref"; } @@ -1906,6 +1930,8 @@ std::ostream& TypePrinter::print(HeapType type) { return os << "extern"; case HeapType::func: return os << "func"; + case HeapType::cont: + return os << "cont"; case HeapType::any: return os << "any"; case HeapType::eq: @@ -1932,6 +1958,8 @@ std::ostream& TypePrinter::print(HeapType type) { return os << "noextern"; case HeapType::nofunc: return os << "nofunc"; + case HeapType::nocont: + return os << "nocont"; case HeapType::noexn: return os << "noexn"; } |