diff options
author | Alon Zakai <azakai@google.com> | 2021-09-02 09:17:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-02 09:17:37 -0700 |
commit | e84980dffb62d672c991960a701a3c7de8f8aa74 (patch) | |
tree | 8e130330f04c3cf10702bc24241061f33591b2f9 /src/wasm/wasm-s-parser.cpp | |
parent | 4bf2d3bc3da17a28b65222d6e84f6126dcb9c553 (diff) | |
download | binaryen-e84980dffb62d672c991960a701a3c7de8f8aa74.tar.gz binaryen-e84980dffb62d672c991960a701a3c7de8f8aa74.tar.bz2 binaryen-e84980dffb62d672c991960a701a3c7de8f8aa74.zip |
Support specialized function types in element segments (#4109)
Before this, the element segments would be printed as having type
funcref, and then if their table had a specialized type, the element
type would not be a subtype of the table and validation would fail.
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index c9c8235e2..c9ca71a6d 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -21,6 +21,7 @@ #include <limits> #include "ir/branch-utils.h" +#include "ir/table-utils.h" #include "shared-constants.h" #include "support/string.h" #include "wasm-binary.h" @@ -3368,6 +3369,11 @@ void SExpressionWasmBuilder::parseElem(Element& s, Table* table) { segment->table = table->name; } + // We may be post-MVP also due to type reasons or otherwise, as detected by + // the utility function for Binaryen IR. + usesExpressions = + usesExpressions || TableUtils::usesExpressions(segment.get(), &wasm); + parseElemFinish(s, segment, i, usesExpressions); } @@ -3377,30 +3383,29 @@ ElementSegment* SExpressionWasmBuilder::parseElemFinish( Index i, bool usesExpressions) { - if (usesExpressions) { - for (; i < s.size(); i++) { - if (!s[i]->isList()) { - throw ParseException("expected a ref.* expression."); - } - auto& inner = *s[i]; - if (elementStartsWith(inner, ITEM)) { - if (inner[1]->isList()) { - // (item (ref.func $f)) - segment->data.push_back(parseExpression(inner[1])); - } else { - // (item ref.func $f) - inner.list().removeAt(0); - segment->data.push_back(parseExpression(inner)); - } - } else { - segment->data.push_back(parseExpression(inner)); - } - } - } else { - for (; i < s.size(); i++) { + for (; i < s.size(); i++) { + if (!s[i]->isList()) { + // An MVP-style declaration: just a function name. auto func = getFunctionName(*s[i]); segment->data.push_back( Builder(wasm).makeRefFunc(func, functionTypes[func])); + continue; + } + if (!usesExpressions) { + throw ParseException("expected an MVP-style $funcname in elem."); + } + auto& inner = *s[i]; + if (elementStartsWith(inner, ITEM)) { + if (inner[1]->isList()) { + // (item (ref.func $f)) + segment->data.push_back(parseExpression(inner[1])); + } else { + // (item ref.func $f) + inner.list().removeAt(0); + segment->data.push_back(parseExpression(inner)); + } + } else { + segment->data.push_back(parseExpression(inner)); } } return wasm.addElementSegment(std::move(segment)); |