summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-s-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r--src/wasm/wasm-s-parser.cpp68
1 files changed, 67 insertions, 1 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 94b434dfb..49cf1ccfc 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2794,7 +2794,7 @@ Expression* SExpressionWasmBuilder::makeTry(Element& s) {
if (!wasm.getTagOrNull(tag)) {
throw SParseException("bad tag name", s, inner);
}
- ret->catchTags.push_back(getTagName(*inner[1]));
+ ret->catchTags.push_back(tag);
ret->catchBodies.push_back(makeMaybeBlock(inner, 2, type));
}
@@ -2837,6 +2837,65 @@ Expression* SExpressionWasmBuilder::makeTry(Element& s) {
return ret;
}
+Expression* SExpressionWasmBuilder::makeTryTable(Element& s) {
+ auto ret = allocator.alloc<TryTable>();
+ Index i = 1;
+ Name sName;
+ if (s.size() > i && s[i]->dollared()) {
+ // the try_table is labeled
+ sName = s[i++]->str();
+ } else {
+ sName = "try_table";
+ }
+ auto label = nameMapper.pushLabelName(sName);
+ Type type = parseBlockType(s, i); // signature
+
+ while (i < s.size()) {
+ Element& inner = *s[i];
+
+ if (elementStartsWith(inner, "catch") ||
+ elementStartsWith(inner, "catch_ref")) {
+ bool isRef = elementStartsWith(inner, "catch_ref");
+ if (inner.size() < 3) {
+ throw SParseException("invalid catch/catch_ref block", s, inner);
+ }
+ Name tag = getTagName(*inner[1]);
+ if (!wasm.getTagOrNull(tag)) {
+ throw SParseException("bad tag name", s, inner);
+ }
+ ret->catchTags.push_back(tag);
+ ret->catchDests.push_back(getLabel(*inner[2]));
+ ret->catchRefs.push_back(isRef);
+ } else if (elementStartsWith(inner, "catch_all") ||
+ elementStartsWith(inner, "catch_all_ref")) {
+ bool isRef = elementStartsWith(inner, "catch_all_ref");
+ if (inner.size() < 2) {
+ throw SParseException(
+ "invalid catch_all/catch_all_ref block", s, inner);
+ }
+ ret->catchTags.push_back(Name());
+ ret->catchDests.push_back(getLabel(*inner[1]));
+ ret->catchRefs.push_back(isRef);
+ } else {
+ break;
+ }
+ i++;
+ }
+
+ ret->body = makeMaybeBlock(s, i, type);
+ ret->finalize(type, &wasm);
+ nameMapper.popLabelName(label);
+ // create a break target if we must
+ if (BranchUtils::BranchSeeker::has(ret, label)) {
+ auto* block = allocator.alloc<Block>();
+ block->name = label;
+ block->list.push_back(ret);
+ block->finalize(type);
+ return block;
+ }
+ return ret;
+}
+
Expression* SExpressionWasmBuilder::makeThrow(Element& s) {
auto ret = allocator.alloc<Throw>();
Index i = 1;
@@ -2859,6 +2918,13 @@ Expression* SExpressionWasmBuilder::makeRethrow(Element& s) {
return ret;
}
+Expression* SExpressionWasmBuilder::makeThrowRef(Element& s) {
+ auto ret = allocator.alloc<ThrowRef>();
+ ret->exnref = parseExpression(s[1]);
+ ret->finalize();
+ return ret;
+}
+
Expression* SExpressionWasmBuilder::makeTupleMake(Element& s) {
auto ret = allocator.alloc<TupleMake>();
size_t arity = std::stoll(s[1]->toString());