diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-03-10 19:26:58 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-03-10 19:26:58 -0800 |
commit | eb1e5b6cc7f32b704bb14b147f47ee7919241503 (patch) | |
tree | 231400a35bb0d59e91646b77eebedd655175c888 /src/wasm-s-parser.h | |
parent | 0467407decb3cd30ad407f553a078b9f533b479d (diff) | |
parent | a8e570c75d3a6cc398a4b1a4c3d492d56c4d8091 (diff) | |
download | binaryen-eb1e5b6cc7f32b704bb14b147f47ee7919241503.tar.gz binaryen-eb1e5b6cc7f32b704bb14b147f47ee7919241503.tar.bz2 binaryen-eb1e5b6cc7f32b704bb14b147f47ee7919241503.zip |
Merge pull request #241 from WebAssembly/spec-updates
Spec updates
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r-- | src/wasm-s-parser.h | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index cfabbf52d..db57dda9f 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -699,22 +699,55 @@ private: } Expression* makeBlock(Element& s) { - auto ret = allocator.alloc<Block>(); - size_t i = 1; - if (i >= s.size()) return ret; // empty block - if (s[i]->isStr()) { - ret->name = s[i]->str(); - i++; - } else { - ret->name = getPrefixedName("block"); + // special-case Block, because Block nesting (in their first element) can be incredibly deep + auto curr = allocator.alloc<Block>(); + auto* sp = &s; + std::vector<std::pair<Element*, Block*>> stack; + while (1) { + stack.emplace_back(sp, curr); + auto& s = *sp; + size_t i = 1; + if (i < s.size() && s[i]->isStr()) { + curr->name = s[i]->str(); + i++; + } else { + curr->name = getPrefixedName("block"); + } + labelStack.push_back(curr->name); + if (i >= s.size()) break; // labeled empty block + auto& first = *s[i]; + if (first[0]->str() == BLOCK) { + // recurse + curr = allocator.alloc<Block>(); + sp = &first; + continue; + } + break; } - labelStack.push_back(ret->name); - for (; i < s.size(); i++) { - ret->list.push_back(parseExpression(s[i])); + // we now have a stack of Blocks, with their labels, but no contents yet + for (int t = int(stack.size()) - 1; t >= 0; t--) { + auto* sp = stack[t].first; + auto* curr = stack[t].second; + auto& s = *sp; + size_t i = 1; + if (i < s.size()) { + if (s[i]->isStr()) { + i++; + } + if (t < int(stack.size()) - 1) { + // first child is one of our recursions + curr->list.push_back(stack[t + 1].second); + i++; + } + for (; i < s.size(); i++) { + curr->list.push_back(parseExpression(s[i])); + } + } + assert(labelStack.back() == curr->name); + labelStack.pop_back(); + curr->finalize(); } - labelStack.pop_back(); - ret->finalize(); - return ret; + return stack[0].second; } // Similar to block, but the label is handled by the enclosing if (since there might not be a then or else, ick) |