diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-03-05 15:52:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-05 15:52:44 -0800 |
commit | 9e3dbb1f668a14341e9aebae479537d4a26095a5 (patch) | |
tree | 9857d50c3373c3f6320ca3f2586bd499bc40b224 /src/wasm/wasm-s-parser.cpp | |
parent | 3a275d0627da443cce93631a64d78e7b3f441416 (diff) | |
download | binaryen-9e3dbb1f668a14341e9aebae479537d4a26095a5.tar.gz binaryen-9e3dbb1f668a14341e9aebae479537d4a26095a5.tar.bz2 binaryen-9e3dbb1f668a14341e9aebae479537d4a26095a5.zip |
Initial multivalue support (#2675)
Implements parsing and emitting of tuple creation and extraction and tuple-typed control flow for both the text and binary formats.
TODO:
- Extend Precompute/interpreter to handle tuple values
- C and JS API support/testing
- Figure out how to lower in stack IR
- Fuzzing
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 573df9dfa..4354b747a 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -538,19 +538,34 @@ SExpressionWasmBuilder::parseParamOrLocal(Element& s, size_t& localIndex) { name = Name::fromInt(localIndex); } localIndex++; - Type type = stringToType(s[i]->str()); + Type type; + if (s[i]->isStr()) { + type = stringToType(s[i]->str()); + } else { + if (elementStartsWith(s, PARAM)) { + throw ParseException( + "params may not have tuple types", s[i]->line, s[i]->col); + } + auto& tuple = s[i]->list(); + std::vector<Type> types; + for (size_t j = 0; j < s[i]->size(); ++j) { + types.push_back(stringToType(tuple[j]->str())); + } + type = Type(types); + } namedParams.emplace_back(name, type); } return namedParams; } // Parses (result type) element. (e.g. (result i32)) -Type SExpressionWasmBuilder::parseResults(Element& s) { +std::vector<Type> SExpressionWasmBuilder::parseResults(Element& s) { assert(elementStartsWith(s, RESULT)); - if (s.size() != 2) { - throw ParseException("invalid result arity", s.line, s.col); + std::vector<Type> types; + for (size_t i = 1; i < s.size(); i++) { + types.push_back(stringToType(s[i]->str())); } - return stringToType(s[1]->str()); + return types; } // Parses an element that references an entry in the type section. The element @@ -599,8 +614,8 @@ SExpressionWasmBuilder::parseTypeUse(Element& s, while (i < s.size() && elementStartsWith(*s[i], RESULT)) { paramsOrResultsExist = true; - // TODO: make parseResults return a vector - results.push_back(parseResults(*s[i++])); + auto newResults = parseResults(*s[i++]); + results.insert(results.end(), newResults.begin(), newResults.end()); } auto inlineSig = Signature(Type(params), Type(results)); @@ -1635,14 +1650,13 @@ Type SExpressionWasmBuilder::parseOptionalResultType(Element& s, Index& i) { return stringToType(s[i++]->str()); } - Element& params = *s[i]; - IString id = params[0]->str(); - if (id != RESULT) { - return Type::none; + Element& results = *s[i]; + IString id = results[0]->str(); + if (id == RESULT) { + i++; + return Type(parseResults(results)); } - - i++; - return stringToType(params[1]->str()); + return Type::none; } Expression* SExpressionWasmBuilder::makeLoop(Element& s) { @@ -1882,6 +1896,21 @@ Expression* SExpressionWasmBuilder::makeBrOnExn(Element& s) { return ret; } +Expression* SExpressionWasmBuilder::makeTupleMake(Element& s) { + auto ret = allocator.alloc<TupleMake>(); + parseCallOperands(s, 1, s.size(), ret); + ret->finalize(); + return ret; +} + +Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) { + auto ret = allocator.alloc<TupleExtract>(); + ret->index = atoi(s[1]->str().c_str()); + ret->tuple = parseExpression(s[2]); + ret->finalize(); + return ret; +} + // converts an s-expression string representing binary data into an output // sequence of raw bytes this appends to data, which may already contain // content. @@ -2440,8 +2469,8 @@ void SExpressionWasmBuilder::parseType(Element& s) { auto newParams = parseParamOrLocal(curr); params.insert(params.end(), newParams.begin(), newParams.end()); } else if (elementStartsWith(curr, RESULT)) { - // TODO: Parse multiple results at once - results.push_back(parseResults(curr)); + auto newResults = parseResults(curr); + results.insert(results.end(), newResults.begin(), newResults.end()); } } signatures.emplace_back(Type(params), Type(results)); |