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.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 4074e4792..6f3fbe76b 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -817,22 +817,36 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
});
finishGroup();
+ auto parseHeapType = [&](Element& elem) -> HeapType {
+ auto name = elem.toString();
+ if (elem.dollared()) {
+ auto it = typeIndices.find(name);
+ if (it == typeIndices.end()) {
+ throw SParseException("invalid type name", elem);
+ } else {
+ return builder[it->second];
+ }
+ } else if (String::isNumber(name)) {
+ size_t index = parseIndex(elem);
+ if (index >= numTypes) {
+ throw SParseException("invalid type index", elem);
+ }
+ return builder[index];
+ } else {
+ return stringToHeapType(elem.str());
+ }
+ };
+
auto parseRefType = [&](Element& elem) -> Type {
// '(' 'ref' 'null'? ht ')'
auto nullable =
elem[1]->isStr() && *elem[1] == NULL_ ? Nullable : NonNullable;
auto& referent = nullable ? *elem[2] : *elem[1];
- auto name = referent.toString();
- if (referent.dollared()) {
- return builder.getTempRefType(builder[typeIndices[name]], nullable);
- } else if (String::isNumber(name)) {
- size_t index = parseIndex(referent);
- if (index >= numTypes) {
- throw SParseException("invalid type index", elem);
- }
- return builder.getTempRefType(builder[index], nullable);
+ auto ht = parseHeapType(referent);
+ if (ht.isBasic()) {
+ return Type(ht, nullable);
} else {
- return Type(stringToHeapType(referent.str()), nullable);
+ return builder.getTempRefType(ht, nullable);
}
};
@@ -886,6 +900,16 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
builder.getTempTupleType(results));
};
+ auto parseContinuationDef = [&](Element& elem) {
+ // '(' 'cont' index ')' | '(' 'cont' name ')'
+ HeapType ft = parseHeapType(*elem[1]);
+ if (!ft.isSignature()) {
+ throw ParseException(
+ "cont type must be created from func type", elem.line, elem.col);
+ }
+ return Continuation(ft);
+ };
+
// Parses a field, and notes the name if one is found.
auto parseField = [&](Element* elem, Name& name) {
Mutability mutable_ = Immutable;
@@ -964,6 +988,8 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
Element& subtypeKind = *subtype[0];
if (subtypeKind == FUNC) {
builder[index] = parseSignatureDef(subtype, 0);
+ } else if (kind == CONT) {
+ builder[index] = parseContinuationDef(subtype);
} else if (subtypeKind == STRUCT) {
builder[index] = parseStructDef(subtype, index, 0);
} else if (subtypeKind == ARRAY) {
@@ -974,6 +1000,8 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
} else {
if (kind == FUNC) {
builder[index] = parseSignatureDef(def, 0);
+ } else if (kind == CONT) {
+ builder[index] = parseContinuationDef(def);
} else if (kind == STRUCT) {
builder[index] = parseStructDef(def, index, 0);
} else if (kind == ARRAY) {