diff options
author | Abbas Mashayekh <martianboy2005@gmail.com> | 2021-04-01 00:30:13 +0430 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-31 13:00:13 -0700 |
commit | d9f0d8f09985320e0849f76d4ce8a8ee409f5e6d (patch) | |
tree | 3c2bc188e95cc066328fb41c359ba45b2ed2d6f6 /src | |
parent | fdd6926c83a5901ba7d7ae12d02f1bd033c92657 (diff) | |
download | binaryen-d9f0d8f09985320e0849f76d4ce8a8ee409f5e6d.tar.gz binaryen-d9f0d8f09985320e0849f76d4ce8a8ee409f5e6d.tar.bz2 binaryen-d9f0d8f09985320e0849f76d4ce8a8ee409f5e6d.zip |
Remove old syntax from table and elem in parser (#3753)
We've been keeping old syntax in the text format parser although they've
been removed from the parser and hardly any test case relies on them.
This PR will remove old syntax support for tables and element segments
and simplify the corresponding parser functions. A few test files were
affected by this that are updated.
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 139 |
1 files changed, 52 insertions, 87 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index d6cef72cd..c1d25f10d 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3178,9 +3178,6 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { std::unique_ptr<Table> table = make_unique<Table>(); Index i = 1; - if (i == s.size()) { - return; // empty table in old notation - } if (s[i]->dollared()) { table->setExplicitName(s[i++]->str()); } else { @@ -3188,10 +3185,6 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { } tableNames.push_back(table->name); - if (i == s.size()) { - wasm.addTable(std::move(table)); - return; - } Name importModule, importBase; if (s[i]->isList()) { auto& inner = *s[i]; @@ -3216,13 +3209,31 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { throw ParseException("invalid table", inner.line, inner.col); } } - if (i == s.size()) { - wasm.addTable(std::move(table)); - return; + + bool hasExplicitLimit = false; + + if (s[i]->isStr() && String::isNumber(s[i]->c_str())) { + table->initial = atoi(s[i++]->c_str()); + hasExplicitLimit = true; + } + + if (s[i]->isStr() && String::isNumber(s[i]->c_str())) { + table->max = atoi(s[i++]->c_str()); + } + + if (!s[i]->isStr() || s[i]->str() != FUNCREF) { + throw ParseException("Expected funcref"); + } else { + i += 1; } - auto parseTableElem = [&](Table* table, Element& s) { - parseElem(s, table); + if (i < s.size() && s[i]->isList()) { + if (hasExplicitLimit) { + throw ParseException( + "Table cannot have both explicit limits and an inline (elem ...)"); + } + // (table type (elem ..)) + parseElem(*s[i], table.get()); auto it = std::find_if(wasm.elementSegments.begin(), wasm.elementSegments.end(), [&](std::unique_ptr<ElementSegment>& segment) { @@ -3233,32 +3244,8 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { } else { table->initial = table->max = 0; } - }; - - if (!s[i]->dollared()) { - if (s[i]->str() == FUNCREF) { - // (table type (elem ..)) - parseTableElem(table.get(), *s[i + 1]); - wasm.addTable(std::move(table)); - return; - } - // first element isn't dollared, and isn't funcref. this could be old syntax - // for (table 0 1) which means function 0 and 1, or it could be (table - // initial max? type), look for type - if (s[s.size() - 1]->str() == FUNCREF) { - // (table initial max? type) - if (i < s.size() - 1) { - table->initial = atoi(s[i++]->c_str()); - } - if (i < s.size() - 1) { - table->max = atoi(s[i++]->c_str()); - } - wasm.addTable(std::move(table)); - return; - } } - // old notation (table func1 func2 ..) - parseTableElem(table.get(), s); + wasm.addTable(std::move(table)); } @@ -3278,14 +3265,14 @@ void SExpressionWasmBuilder::parseElem(Element& s, Table* table) { Index i = 1; Name name = Name::fromInt(elemCounter++); bool hasExplicitName = false; - bool isPassive = false; + bool isPassive = true; bool usesExpressions = false; if (table) { Expression* offset = allocator.alloc<Const>()->set(Literal(int32_t(0))); auto segment = std::make_unique<ElementSegment>(table->name, offset); segment->setName(name, hasExplicitName); - parseElemFinish(s, segment, i, false); + parseElemFinish(s, segment, i, s[i]->isList()); return; } @@ -3298,70 +3285,48 @@ void SExpressionWasmBuilder::parseElem(Element& s, Table* table) { return; } - if (s[i]->isStr()) { - if (s[i]->str() == FUNC) { - isPassive = true; - usesExpressions = false; - } else if (s[i]->str() == FUNCREF) { - isPassive = true; - usesExpressions = true; - } - } - - if (isPassive) { - auto segment = std::make_unique<ElementSegment>(); - segment->setName(name, hasExplicitName); - parseElemFinish(s, segment, i + 1, usesExpressions); - return; - } - - // old style refers to the pre-reftypes form of (elem 0? (expr) vec(funcidx)) - bool oldStyle = true; - - // At this point, we know that we're parsing an active element segment. A - // table will be mandatory now. - if (wasm.tables.empty()) { - throw ParseException("elem without table", s.line, s.col); - } - - // Old style table index (elem 0 (i32.const 0) ...) - if (s[i]->isStr()) { - i += 1; - } - - if (s[i]->isList() && elementStartsWith(s[i], TABLE)) { - oldStyle = false; - auto& inner = *s[i++]; - Name tableName = getTableName(*inner[1]); - table = wasm.getTable(tableName); - } + auto segment = std::make_unique<ElementSegment>(); + segment->setName(name, hasExplicitName); - Expression* offset = nullptr; if (s[i]->isList()) { + // Optional (table <tableidx>) + if (elementStartsWith(s[i], TABLE)) { + auto& inner = *s[i++]; + segment->table = getTableName(*inner[1]); + } + + // Offset expression (offset (<expr>)) | (<expr>) auto& inner = *s[i++]; if (elementStartsWith(inner, OFFSET)) { - offset = parseExpression(inner[1]); - oldStyle = false; + segment->offset = parseExpression(inner[1]); } else { - offset = parseExpression(inner); + segment->offset = parseExpression(inner); } + isPassive = false; } - if (!oldStyle) { - if (s[i]->str() == FUNCREF) { + if (i < s.size()) { + if (s[i]->isStr() && s[i]->dollared()) { + usesExpressions = false; + } else if (s[i]->isStr() && s[i]->str() == FUNC) { + usesExpressions = false; + i += 1; + } else if (s[i]->isStr() && s[i]->str() == FUNCREF) { usesExpressions = true; - } else if (s[i]->str() != FUNC) { + i += 1; + } else { throw ParseException("expected func or funcref."); } - i += 1; } - if (!table) { + if (!isPassive && segment->table.isNull()) { + if (wasm.tables.empty()) { + throw ParseException("active element without table", s.line, s.col); + } table = wasm.tables.front().get(); + segment->table = table->name; } - auto segment = std::make_unique<ElementSegment>(table->name, offset); - segment->setName(name, hasExplicitName); parseElemFinish(s, segment, i, usesExpressions); } |