summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp4
-rw-r--r--src/tools/fuzzing/fuzzing.cpp7
-rw-r--r--src/tools/fuzzing/heap-types.cpp6
-rw-r--r--src/wasm-binary.h4
-rw-r--r--src/wasm-type.h6
-rw-r--r--src/wasm/literal.cpp6
-rw-r--r--src/wasm/wasm-binary.cpp24
-rw-r--r--src/wasm/wasm-s-parser.cpp12
-rw-r--r--src/wasm/wasm-type.cpp40
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";
}