summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2023-12-08 15:03:09 -0800
committerGitHub <noreply@github.com>2023-12-08 15:03:09 -0800
commit1d615b38dd4152494d2f4d3520c8b1d917624a30 (patch)
tree40a32cc670c62e1fb5bdfcfda9f65d35d721956f
parent48373b66e613b7e626322b595ae6551582acc6c2 (diff)
downloadbinaryen-1d615b38dd4152494d2f4d3520c8b1d917624a30.tar.gz
binaryen-1d615b38dd4152494d2f4d3520c8b1d917624a30.tar.bz2
binaryen-1d615b38dd4152494d2f4d3520c8b1d917624a30.zip
[EH] Add exnref type back (#6149)
At the Oct hybrid CG meeting, we decided to add back `exnref`, which was removed in 2020: https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md The new version of the proposal reflected in the explainer: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md While adding support for `exnref` in the current codebase which has all GC subtype hierarchies, I noticed we might need `noexn` heap type for the bottom type of `exn`. We don't have it now so I just set it to 0xff for the moment.
-rw-r--r--src/binaryen-c.cpp4
-rw-r--r--src/tools/fuzzing/fuzzing.cpp14
-rw-r--r--src/tools/fuzzing/heap-types.cpp9
-rw-r--r--src/wasm-binary.h19
-rw-r--r--src/wasm-type.h9
-rw-r--r--src/wasm/literal.cpp8
-rw-r--r--src/wasm/wasm-binary.cpp30
-rw-r--r--src/wasm/wasm-s-parser.cpp15
-rw-r--r--src/wasm/wasm-type.cpp34
-rw-r--r--test/example/c-api-kitchen-sink.txt14
-rw-r--r--test/exception-handling.wast18
-rw-r--r--test/exception-handling.wast.from-wast14
-rw-r--r--test/exception-handling.wast.fromBinary14
-rw-r--r--test/exception-handling.wast.fromBinary.noDebugInfo14
14 files changed, 198 insertions, 18 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index b53f5fd0c..c273a3af4 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -87,6 +87,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
case HeapType::func:
case HeapType::struct_:
case HeapType::array:
+ case HeapType::exn:
WASM_UNREACHABLE("invalid type");
case HeapType::string:
case HeapType::stringview_wtf8:
@@ -96,6 +97,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) {
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ case HeapType::noexn:
// Null.
return ret;
}
@@ -140,6 +142,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
case HeapType::func:
case HeapType::struct_:
case HeapType::array:
+ case HeapType::exn:
WASM_UNREACHABLE("invalid type");
case HeapType::string:
case HeapType::stringview_wtf8:
@@ -149,6 +152,7 @@ Literal fromBinaryenLiteral(BinaryenLiteral x) {
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ 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 d9e0f6baf..07464af9d 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -2429,6 +2429,14 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
HeapType(Array(Field(Field::PackedType::i8, Immutable)));
return builder.makeArrayNewFixed(trivialArray, {});
}
+ case HeapType::exn: {
+ auto null = builder.makeRefNull(HeapType::ext);
+ if (!type.isNullable()) {
+ assert(funcContext);
+ return builder.makeRefAs(RefAsNonNull, null);
+ }
+ return null;
+ }
case HeapType::string:
return builder.makeStringConst(std::to_string(upTo(1024)));
case HeapType::stringview_wtf8:
@@ -2437,7 +2445,8 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
WASM_UNREACHABLE("TODO: strings");
case HeapType::none:
case HeapType::noext:
- case HeapType::nofunc: {
+ case HeapType::nofunc:
+ case HeapType::noexn: {
auto null = builder.makeRefNull(heapType);
if (!type.isNullable()) {
assert(funcContext);
@@ -3888,6 +3897,8 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) {
return pick(HeapType::struct_, HeapType::none);
case HeapType::array:
return pick(HeapType::array, HeapType::none);
+ case HeapType::exn:
+ return HeapType::exn;
case HeapType::string:
return HeapType::string;
case HeapType::stringview_wtf8:
@@ -3897,6 +3908,7 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) {
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ case HeapType::noexn:
break;
}
}
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index 32a3fd960..13ad01474 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -378,8 +378,6 @@ struct HeapTypeGeneratorImpl {
return type.getBottom();
}
switch (type.getBasic()) {
- case HeapType::ext:
- return HeapType::ext;
case HeapType::func:
return pickSubFunc();
case HeapType::any:
@@ -392,6 +390,8 @@ struct HeapTypeGeneratorImpl {
return pickSubStruct();
case HeapType::array:
return pickSubArray();
+ case HeapType::ext:
+ case HeapType::exn:
case HeapType::string:
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
@@ -399,6 +399,7 @@ struct HeapTypeGeneratorImpl {
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ case HeapType::noexn:
return type;
}
WASM_UNREACHABLE("unexpected type");
@@ -440,6 +441,7 @@ struct HeapTypeGeneratorImpl {
switch (type.getBasic()) {
case HeapType::ext:
case HeapType::func:
+ case HeapType::exn:
case HeapType::any:
break;
case HeapType::eq:
@@ -464,6 +466,9 @@ struct HeapTypeGeneratorImpl {
case HeapType::noext:
candidates.push_back(HeapType::ext);
break;
+ case HeapType::noexn:
+ candidates.push_back(HeapType::exn);
+ break;
}
assert(!candidates.empty());
return rand.pick(candidates);
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 752f306fe..58d641dc9 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -412,6 +412,9 @@ enum EncodedType {
nullable = -0x14, // 0x6c
nonnullable = -0x15, // 0x6b
#endif
+ // exception handling
+ exnref = -0x17, // 0x69
+ nullexnref = -0xff, // TODO
// string reference types
#if STANDARD_GC_ENCODINGS
stringref = -0x19, // 0x67
@@ -449,14 +452,16 @@ enum EncodedHeapType {
noext = -0xe, // 0x72
none = -0xf, // 0x71
#else
- noext = -0x17, // 0x69
- nofunc = -0x18, // 0x68
- none = -0x1b, // 0x65
+ noext = -0x17, // 0x69
+ nofunc = -0x18, // 0x68
+ none = -0x1b, // 0x65
#endif
- func = -0x10, // 0x70
- ext = -0x11, // 0x6f
- any = -0x12, // 0x6e
- eq = -0x13, // 0x6d
+ func = -0x10, // 0x70
+ ext = -0x11, // 0x6f
+ any = -0x12, // 0x6e
+ eq = -0x13, // 0x6d
+ exn = -0x17, // 0x69
+ noexn = -0xff, // TODO
#if STANDARD_GC_ENCODINGS
i31 = -0x14, // 0x6c
struct_ = -0x15, // 0x6b
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 573cd9102..5c47f4051 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -137,6 +137,9 @@ public:
// │ eqref ║ x │ │ x │ x │ n │ │ n_ullable
// │ i31ref ║ x │ │ x │ x │ n │ │
// │ structref ║ x │ │ x │ x │ n │ │
+ // │ arrayref ║ x │ │ x │ x │ n │ │
+ // │ exnref ║ x │ │ x │ x │ n │ │
+ // │ stringref ║ x │ │ x │ x │ n │ │
// ├─ Compound ──╫───┼───┼───┼───┤───────┤ │
// │ Ref ║ │ x │ x │ x │ f? n? │◄┘
// │ Tuple ║ │ x │ │ x │ │
@@ -167,6 +170,7 @@ public:
bool isSignature() const;
bool isStruct() const;
bool isArray() const;
+ bool isException() const;
bool isString() const;
bool isDefaultable() const;
@@ -322,6 +326,7 @@ public:
i31,
struct_,
array,
+ exn,
string,
stringview_wtf8,
stringview_wtf16,
@@ -329,8 +334,9 @@ public:
none,
noext,
nofunc,
+ noexn,
};
- static constexpr BasicHeapType _last_basic_type = nofunc;
+ static constexpr BasicHeapType _last_basic_type = noexn;
// BasicHeapType can be implicitly upgraded to HeapType
constexpr HeapType(BasicHeapType id) : id(id) {}
@@ -364,6 +370,7 @@ public:
bool isContinuation() const;
bool isStruct() const;
bool isArray() const;
+ bool isException() const;
bool isString() const;
bool isBottom() const;
bool isOpen() const;
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 4bae54693..7c674ffc5 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -133,12 +133,14 @@ Literal::Literal(const Literal& other) : type(other.type) {
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ case HeapType::noexn:
WASM_UNREACHABLE("null literals should already have been handled");
case HeapType::any:
case HeapType::eq:
case HeapType::func:
case HeapType::struct_:
case HeapType::array:
+ case HeapType::exn:
WASM_UNREACHABLE("invalid type");
case HeapType::string:
case HeapType::stringview_wtf8:
@@ -613,9 +615,15 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
case HeapType::nofunc:
o << "nullfuncref";
break;
+ case HeapType::noexn:
+ o << "nullexnref";
+ break;
case HeapType::ext:
o << "externref";
break;
+ case HeapType::exn:
+ o << "exnref";
+ break;
case HeapType::any:
case HeapType::eq:
case HeapType::func:
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 3c01e5df5..be1c27d03 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1472,6 +1472,10 @@ void WasmBinaryWriter::writeType(Type type) {
o << S32LEB(BinaryConsts::EncodedType::externref);
return;
}
+ if (Type::isSubType(type, Type(HeapType::exn, Nullable))) {
+ o << S32LEB(BinaryConsts::EncodedType::exnref);
+ return;
+ }
if (Type::isSubType(type, Type(HeapType::string, Nullable))) {
o << S32LEB(BinaryConsts::EncodedType::stringref);
return;
@@ -1502,6 +1506,9 @@ void WasmBinaryWriter::writeType(Type type) {
case HeapType::array:
o << S32LEB(BinaryConsts::EncodedType::arrayref);
return;
+ case HeapType::exn:
+ o << S32LEB(BinaryConsts::EncodedType::exnref);
+ return;
case HeapType::string:
o << S32LEB(BinaryConsts::EncodedType::stringref);
return;
@@ -1523,6 +1530,9 @@ void WasmBinaryWriter::writeType(Type type) {
case HeapType::nofunc:
o << S32LEB(BinaryConsts::EncodedType::nullfuncref);
return;
+ case HeapType::noexn:
+ o << S32LEB(BinaryConsts::EncodedType::nullexnref);
+ return;
}
}
if (type.isNullable()) {
@@ -1570,6 +1580,8 @@ void WasmBinaryWriter::writeHeapType(HeapType type) {
type = HeapType::func;
} else if (HeapType::isSubType(type, HeapType::ext)) {
type = HeapType::ext;
+ } else if (HeapType::isSubType(type, HeapType::exn)) {
+ type = HeapType::exn;
} else if (wasm->features.hasStrings()) {
// Strings are enabled, and this isn't a func or an ext, so it must be a
// string type (string or stringview), which we'll emit below, or a bottom
@@ -1609,6 +1621,9 @@ void WasmBinaryWriter::writeHeapType(HeapType type) {
case HeapType::array:
ret = BinaryConsts::EncodedHeapType::array;
break;
+ case HeapType::exn:
+ ret = BinaryConsts::EncodedHeapType::exn;
+ break;
case HeapType::string:
ret = BinaryConsts::EncodedHeapType::string;
break;
@@ -1630,6 +1645,9 @@ void WasmBinaryWriter::writeHeapType(HeapType type) {
case HeapType::nofunc:
ret = BinaryConsts::EncodedHeapType::nofunc;
break;
+ case HeapType::noexn:
+ ret = BinaryConsts::EncodedHeapType::noexn;
+ break;
}
o << S64LEB(ret); // TODO: Actually s33
}
@@ -1980,6 +1998,9 @@ bool WasmBinaryReader::getBasicType(int32_t code, Type& out) {
case BinaryConsts::EncodedType::arrayref:
out = Type(HeapType::array, Nullable);
return true;
+ case BinaryConsts::EncodedType::exnref:
+ out = Type(HeapType::exn, Nullable);
+ return true;
case BinaryConsts::EncodedType::stringref:
out = Type(HeapType::string, Nullable);
return true;
@@ -2001,6 +2022,9 @@ bool WasmBinaryReader::getBasicType(int32_t code, Type& out) {
case BinaryConsts::EncodedType::nullfuncref:
out = Type(HeapType::nofunc, Nullable);
return true;
+ case BinaryConsts::EncodedType::nullexnref:
+ out = Type(HeapType::noexn, Nullable);
+ return true;
default:
return false;
}
@@ -2029,6 +2053,9 @@ bool WasmBinaryReader::getBasicHeapType(int64_t code, HeapType& out) {
case BinaryConsts::EncodedHeapType::array:
out = HeapType::array;
return true;
+ case BinaryConsts::EncodedHeapType::exn:
+ out = HeapType::exn;
+ return true;
case BinaryConsts::EncodedHeapType::string:
out = HeapType::string;
return true;
@@ -2050,6 +2077,9 @@ bool WasmBinaryReader::getBasicHeapType(int64_t code, HeapType& out) {
case BinaryConsts::EncodedHeapType::nofunc:
out = HeapType::nofunc;
return true;
+ case BinaryConsts::EncodedHeapType::noexn:
+ out = HeapType::noexn;
+ return true;
default:
return false;
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 7b415813e..9e16d34e6 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1279,6 +1279,9 @@ Type SExpressionWasmBuilder::stringToType(std::string_view str,
if (str.substr(0, 8) == "arrayref" && (prefix || str.size() == 8)) {
return Type(HeapType::array, Nullable);
}
+ if (str.substr(0, 6) == "exnref" && (prefix || str.size() == 6)) {
+ return Type(HeapType::exn, Nullable);
+ }
if (str.substr(0, 9) == "stringref" && (prefix || str.size() == 9)) {
return Type(HeapType::string, Nullable);
}
@@ -1300,6 +1303,9 @@ Type SExpressionWasmBuilder::stringToType(std::string_view str,
if (str.substr(0, 11) == "nullfuncref" && (prefix || str.size() == 11)) {
return Type(HeapType::nofunc, Nullable);
}
+ if (str.substr(0, 10) == "nullexnref" && (prefix || str.size() == 10)) {
+ return Type(HeapType::noexn, Nullable);
+ }
if (allowError) {
return Type::none;
}
@@ -1330,6 +1336,9 @@ HeapType SExpressionWasmBuilder::stringToHeapType(std::string_view str,
if (str.substr(0, 5) == "array" && (prefix || str.size() == 5)) {
return HeapType::array;
}
+ if (str.substr(0, 3) == "exn" && (prefix || str.size() == 3)) {
+ return HeapType::exn;
+ }
if (str.substr(0, 6) == "string" && (prefix || str.size() == 6)) {
return HeapType::string;
}
@@ -1351,6 +1360,12 @@ HeapType SExpressionWasmBuilder::stringToHeapType(std::string_view str,
if (str.substr(0, 6) == "nofunc" && (prefix || str.size() == 6)) {
return HeapType::nofunc;
}
+ if (str.substr(0, 6) == "nofunc" && (prefix || str.size() == 6)) {
+ return HeapType::nofunc;
+ }
+ if (str.substr(0, 5) == "noexn" && (prefix || str.size() == 5)) {
+ return HeapType::noexn;
+ }
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 dce0eb645..97a8cba0e 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -472,6 +472,7 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a,
switch (a) {
case HeapType::ext:
case HeapType::func:
+ case HeapType::exn:
return std::nullopt;
case HeapType::any:
return {HeapType::any};
@@ -500,6 +501,7 @@ std::optional<HeapType> getBasicHeapTypeLUB(HeapType::BasicHeapType a,
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ case HeapType::noexn:
// Bottom types already handled.
break;
}
@@ -801,6 +803,10 @@ bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); }
bool Type::isArray() const { return isRef() && getHeapType().isArray(); }
+bool Type::isException() const {
+ return isRef() && getHeapType().isException();
+}
+
bool Type::isString() const { return isRef() && getHeapType().isString(); }
bool Type::isDefaultable() const {
@@ -917,6 +923,11 @@ FeatureSet Type::getFeatures() const {
// ref.null with just reference types.
feats |= FeatureSet::ReferenceTypes;
return;
+ case HeapType::exn:
+ case HeapType::noexn:
+ feats |=
+ FeatureSet::ExceptionHandling | FeatureSet::ReferenceTypes;
+ return;
}
}
@@ -1190,6 +1201,8 @@ bool HeapType::isArray() const {
}
}
+bool HeapType::isException() const { return *this == HeapType::exn; }
+
bool HeapType::isString() const { return *this == HeapType::string; }
bool HeapType::isBottom() const {
@@ -1202,6 +1215,7 @@ bool HeapType::isBottom() const {
case i31:
case struct_:
case array:
+ case exn:
case string:
case stringview_wtf8:
case stringview_wtf16:
@@ -1210,6 +1224,7 @@ bool HeapType::isBottom() const {
case none:
case noext:
case nofunc:
+ case noexn:
return true;
}
}
@@ -1270,6 +1285,8 @@ std::optional<HeapType> HeapType::getSuperType() const {
case nofunc:
case any:
case none:
+ case exn:
+ case noexn:
case string:
case stringview_wtf8:
case stringview_wtf16:
@@ -1326,6 +1343,7 @@ size_t HeapType::getDepth() const {
case HeapType::ext:
case HeapType::func:
case HeapType::any:
+ case HeapType::exn:
break;
case HeapType::eq:
depth++;
@@ -1342,6 +1360,7 @@ size_t HeapType::getDepth() const {
case HeapType::none:
case HeapType::nofunc:
case HeapType::noext:
+ case HeapType::noexn:
// Bottom types are infinitely deep.
depth = size_t(-1l);
}
@@ -1356,6 +1375,8 @@ HeapType::BasicHeapType HeapType::getBottom() const {
return noext;
case func:
return nofunc;
+ case exn:
+ return noexn;
case any:
case eq:
case i31:
@@ -1371,6 +1392,8 @@ HeapType::BasicHeapType HeapType::getBottom() const {
return noext;
case nofunc:
return nofunc;
+ case noexn:
+ return noexn;
}
}
auto* info = getHeapTypeInfo(*this);
@@ -1672,6 +1695,8 @@ bool SubTyper::isSubType(HeapType a, HeapType b) {
return a.getBottom() == HeapType::noext;
case HeapType::func:
return a.getBottom() == HeapType::nofunc;
+ case HeapType::exn:
+ return a.getBottom() == HeapType::noexn;
case HeapType::any:
return a.getBottom() == HeapType::none;
case HeapType::eq:
@@ -1692,6 +1717,7 @@ bool SubTyper::isSubType(HeapType a, HeapType b) {
case HeapType::none:
case HeapType::noext:
case HeapType::nofunc:
+ case HeapType::noexn:
return false;
}
}
@@ -1816,6 +1842,8 @@ std::ostream& TypePrinter::print(Type type) {
return os << "structref";
case HeapType::array:
return os << "arrayref";
+ case HeapType::exn:
+ return os << "exnref";
case HeapType::string:
return os << "stringref";
case HeapType::stringview_wtf8:
@@ -1830,6 +1858,8 @@ std::ostream& TypePrinter::print(Type type) {
return os << "nullexternref";
case HeapType::nofunc:
return os << "nullfuncref";
+ case HeapType::noexn:
+ return os << "nullexnref";
}
}
}
@@ -1862,6 +1892,8 @@ std::ostream& TypePrinter::print(HeapType type) {
return os << "struct";
case HeapType::array:
return os << "array";
+ case HeapType::exn:
+ return os << "exn";
case HeapType::string:
return os << "string";
case HeapType::stringview_wtf8:
@@ -1876,6 +1908,8 @@ std::ostream& TypePrinter::print(HeapType type) {
return os << "noextern";
case HeapType::nofunc:
return os << "nofunc";
+ case HeapType::noexn:
+ return os << "noexn";
}
}
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index 2a3ecea9d..d682285d1 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -30,13 +30,13 @@ BinaryenHeapTypeEq: 3
BinaryenHeapTypeI31: 4
BinaryenHeapTypeStruct: 5
BinaryenHeapTypeArray: 6
-BinaryenHeapTypeString: 7
-BinaryenHeapTypeStringviewWTF8: 8
-BinaryenHeapTypeStringviewWTF16: 9
-BinaryenHeapTypeStringviewIter: 10
-BinaryenHeapTypeNone: 11
-BinaryenHeapTypeNoext: 12
-BinaryenHeapTypeNofunc: 13
+BinaryenHeapTypeString: 8
+BinaryenHeapTypeStringviewWTF8: 9
+BinaryenHeapTypeStringviewWTF16: 10
+BinaryenHeapTypeStringviewIter: 11
+BinaryenHeapTypeNone: 12
+BinaryenHeapTypeNoext: 13
+BinaryenHeapTypeNofunc: 14
BinaryenFeatureMVP: 0
BinaryenFeatureAtomics: 1
BinaryenFeatureBulkMemory: 16
diff --git a/test/exception-handling.wast b/test/exception-handling.wast
index d37cc322b..1a484f9ac 100644
--- a/test/exception-handling.wast
+++ b/test/exception-handling.wast
@@ -8,6 +8,9 @@
(func $foo)
(func $bar)
+ ;; ---------------------------------------------------------------------------
+ ;; Old Phase 3 exception handling
+
(func $eh-test (local $x (i32 i64))
;; Simple try-catch
(try
@@ -365,4 +368,19 @@
)
(nop)
)
+
+ ;; ---------------------------------------------------------------------------
+ ;; New exception handling
+
+ (func $exnref-test (result exnref) (local $exn exnref) (local $null-exn nullexnref)
+ (if (result exnref)
+ (i32.const 1)
+ (if (result nullexnref)
+ (i32.const 1)
+ (local.get $null-exn)
+ (ref.null noexn)
+ )
+ (local.get $exn)
+ )
+ )
)
diff --git a/test/exception-handling.wast.from-wast b/test/exception-handling.wast.from-wast
index da9a1031e..7e7bec6ff 100644
--- a/test/exception-handling.wast.from-wast
+++ b/test/exception-handling.wast.from-wast
@@ -4,6 +4,7 @@
(type $2 (func (param i64)))
(type $3 (func (param i32 i64)))
(type $4 (func (param eqref)))
+ (type $5 (func (result exnref)))
(tag $e-i32 (param i32))
(tag $e-i64 (param i64))
(tag $e-i32-i64 (param i32 i64))
@@ -406,4 +407,17 @@
)
(nop)
)
+ (func $exnref-test (type $5) (result exnref)
+ (local $exn exnref)
+ (local $null-exn nullexnref)
+ (if (result exnref)
+ (i32.const 1)
+ (if (result nullexnref)
+ (i32.const 1)
+ (local.get $null-exn)
+ (ref.null noexn)
+ )
+ (local.get $exn)
+ )
+ )
)
diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary
index e9cfce409..93678bc6f 100644
--- a/test/exception-handling.wast.fromBinary
+++ b/test/exception-handling.wast.fromBinary
@@ -4,6 +4,7 @@
(type $2 (func (param i64)))
(type $3 (func (param i32 i64)))
(type $4 (func (param eqref)))
+ (type $5 (func (result exnref)))
(tag $e-i32 (param i32))
(tag $e-i64 (param i64))
(tag $e-i32-i64 (param i32 i64))
@@ -428,5 +429,18 @@
)
(nop)
)
+ (func $exnref-test (type $5) (result exnref)
+ (local $exn exnref)
+ (local $null-exn nullexnref)
+ (if (result exnref)
+ (i32.const 1)
+ (if (result nullexnref)
+ (i32.const 1)
+ (local.get $null-exn)
+ (ref.null noexn)
+ )
+ (local.get $exn)
+ )
+ )
)
diff --git a/test/exception-handling.wast.fromBinary.noDebugInfo b/test/exception-handling.wast.fromBinary.noDebugInfo
index 4bc460630..beea8498b 100644
--- a/test/exception-handling.wast.fromBinary.noDebugInfo
+++ b/test/exception-handling.wast.fromBinary.noDebugInfo
@@ -4,6 +4,7 @@
(type $2 (func (param i64)))
(type $3 (func (param i32 i64)))
(type $4 (func (param eqref)))
+ (type $5 (func (result exnref)))
(tag $tag$0 (param i32))
(tag $tag$1 (param i64))
(tag $tag$2 (param i32 i64))
@@ -428,5 +429,18 @@
)
(nop)
)
+ (func $8 (type $5) (result exnref)
+ (local $0 exnref)
+ (local $1 nullexnref)
+ (if (result exnref)
+ (i32.const 1)
+ (if (result nullexnref)
+ (i32.const 1)
+ (local.get $1)
+ (ref.null noexn)
+ )
+ (local.get $0)
+ )
+ )
)