diff options
author | Andy Wingo <wingo@pobox.com> | 2023-04-03 16:59:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-03 08:59:15 -0700 |
commit | 382671ba0f673dd5da6bcaf6756fc43a518a41f6 (patch) | |
tree | 9035b2d9681803c6530bbd67286ff1631e51bf02 /src | |
parent | 47056c9a00e368969a503209b6b9f5c0bc287058 (diff) | |
download | binaryen-382671ba0f673dd5da6bcaf6756fc43a518a41f6.tar.gz binaryen-382671ba0f673dd5da6bcaf6756fc43a518a41f6.tar.bz2 binaryen-382671ba0f673dd5da6bcaf6756fc43a518a41f6.zip |
[Wasm GC] Parse (sub $super _) for array, func, and struct (#5515)
The pretty-printer will still serialize these using the old
func_subtype, array_subtype, and struct_subtype syntax, though.
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index b7f88f4c1..1afdefe87 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -52,7 +52,7 @@ namespace wasm { static Name STRUCT("struct"), FIELD("field"), ARRAY("array"), FUNC_SUBTYPE("func_subtype"), STRUCT_SUBTYPE("struct_subtype"), ARRAY_SUBTYPE("array_subtype"), EXTENDS("extends"), REC("rec"), I8("i8"), - I16("i16"), DECLARE("declare"), ITEM("item"), OFFSET("offset"); + I16("i16"), DECLARE("declare"), ITEM("item"), OFFSET("offset"), SUB("sub"); static Address getAddress(const Element* s) { return std::stoll(s->toString()); @@ -898,30 +898,62 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { forEachType([&](Element& elem, size_t) { Element& def = elem[1]->dollared() ? *elem[2] : *elem[1]; Element& kind = *def[0]; - bool hasSupertype = - kind == FUNC_SUBTYPE || kind == STRUCT_SUBTYPE || kind == ARRAY_SUBTYPE; - if (kind == FUNC || kind == FUNC_SUBTYPE) { - builder[index] = parseSignatureDef(def, hasSupertype); - } else if (kind == STRUCT || kind == STRUCT_SUBTYPE) { - builder[index] = parseStructDef(def, index, hasSupertype); - } else if (kind == ARRAY || kind == ARRAY_SUBTYPE) { - builder[index] = parseArrayDef(def); - } else { - throw ParseException("unknown heaptype kind", kind.line, kind.col); - } Element* super = nullptr; - if (hasSupertype) { - super = def[def.size() - 1]; - if (super->dollared()) { - // OK - } else if (kind == FUNC_SUBTYPE && super->str() == FUNC) { - // OK; no supertype - super = nullptr; - } else if ((kind == STRUCT_SUBTYPE || kind == ARRAY_SUBTYPE) && - super->str() == DATA) { - // OK; no supertype - super = nullptr; + if (kind == SUB) { + if (def.size() != 3) { + throw ParseException("invalid 'sub' form", kind.line, kind.col); + } + super = def[1]; + Element& subtype = *def[2]; + if (!subtype.isList() || subtype.size() < 1) { + throw ParseException( + "invalid subtype definition", subtype.line, subtype.col); + } + Element& subtypeKind = *subtype[0]; + if (subtypeKind == FUNC) { + builder[index] = parseSignatureDef(subtype, 0); + } else if (subtypeKind == STRUCT) { + builder[index] = parseStructDef(subtype, index, 0); + } else if (subtypeKind == ARRAY) { + builder[index] = parseArrayDef(subtype); + } else { + throw ParseException( + "unknown subtype kind", subtypeKind.line, subtypeKind.col); + } + } else { + if (kind == FUNC) { + builder[index] = parseSignatureDef(def, 0); + } else if (kind == FUNC_SUBTYPE) { + builder[index] = parseSignatureDef(def, 1); + super = def[def.size() - 1]; + if (!super->dollared() && super->str() == FUNC) { + // OK; no supertype + super = nullptr; + } + } else if (kind == STRUCT) { + builder[index] = parseStructDef(def, index, 0); + } else if (kind == STRUCT_SUBTYPE) { + builder[index] = parseStructDef(def, index, 1); + super = def[def.size() - 1]; + if (!super->dollared() && super->str() == DATA) { + // OK; no supertype + super = nullptr; + } + } else if (kind == ARRAY) { + builder[index] = parseArrayDef(def); + } else if (kind == ARRAY_SUBTYPE) { + builder[index] = parseArrayDef(def); + super = def[def.size() - 1]; + if (!super->dollared() && super->str() == DATA) { + // OK; no supertype + super = nullptr; + } } else { + throw ParseException("unknown heaptype kind", kind.line, kind.col); + } + } + if (super) { + if (!super->dollared()) { throw ParseException("unknown supertype", super->line, super->col); } } else if (elementStartsWith(elem[elem.size() - 1], EXTENDS)) { |