diff options
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r-- | src/wasm-s-parser.h | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 72949eb2b..7f5afe8f7 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -428,16 +428,9 @@ private: std::map<Name, WasmType> currLocalTypes; size_t localIndex; // params and vars size_t otherIndex; - std::vector<Name> labelStack; bool brokeToAutoBlock; - Name getPrefixedName(std::string prefix) { - // make sure to return a unique name not already on the stack - while (1) { - Name ret = IString((prefix + std::to_string(otherIndex++)).c_str(), false); - if (std::find(labelStack.begin(), labelStack.end(), ret) == labelStack.end()) return ret; - } - } + UniqueNameMapper nameMapper; Name getFunctionName(Element& s) { if (s.dollared()) { @@ -642,7 +635,7 @@ private: wasm.addImport(im.release()); assert(!currFunction); currLocalTypes.clear(); - labelStack.clear(); + nameMapper.clear(); return; } assert(!preParseImport); @@ -662,7 +655,7 @@ private: currFunction->type = type; wasm.addFunction(currFunction.release()); currLocalTypes.clear(); - labelStack.clear(); + nameMapper.clear(); } WasmType stringToWasmType(IString str, bool allowError=false, bool prefix=false) { @@ -1085,18 +1078,18 @@ private: stack.emplace_back(sp, curr); auto& s = *sp; size_t i = 1; + Name sName; if (i < s.size() && s[i]->isStr()) { // could be a name or a type if (s[i]->dollared() || stringToWasmType(s[i]->str(), true /* allowError */) == none) { - curr->name = s[i]->str(); - i++; + sName = s[i++]->str(); } else { - curr->name = getPrefixedName("block"); + sName = "block"; } } else { - curr->name = getPrefixedName("block"); + sName = "block"; } - labelStack.push_back(curr->name); + curr->name = nameMapper.pushLabelName(sName); if (i >= s.size()) break; // empty block if (s[i]->isStr()) { // block signature @@ -1133,8 +1126,7 @@ private: curr->list.push_back(parseExpression(s[i])); } } - assert(labelStack.back() == curr->name); - labelStack.pop_back(); + nameMapper.popLabelName(curr->name); curr->finalize(curr->type); } return stack[0].second; @@ -1240,14 +1232,14 @@ private: Expression* makeIf(Element& s) { auto ret = allocator.alloc<If>(); Index i = 1; - Name label; + Name sName; if (s[i]->dollared()) { // the if is labeled - label = s[i++]->str(); + sName = s[i++]->str(); } else { - label = getPrefixedName("if"); + sName = "if"; } - labelStack.push_back(label); + auto label = nameMapper.pushLabelName(sName); WasmType type = none; if (s[i]->isStr()) { type = stringToWasmType(s[i++]->str()); @@ -1258,7 +1250,7 @@ private: ret->ifFalse = parseExpression(*s[i++]); } ret->finalize(type); - labelStack.pop_back(); + nameMapper.popLabelName(label); // create a break target if we must if (BreakSeeker::has(ret, label)) { auto* block = allocator.alloc<Block>(); @@ -1288,33 +1280,21 @@ private: Expression* makeLoop(Element& s) { auto ret = allocator.alloc<Loop>(); size_t i = 1; - Name out; - if (s.size() > i + 1 && s[i]->dollared() && s[i + 1]->dollared()) { // out can only be named if both are - out = s[i]->str(); - i++; - } + Name sName; if (s.size() > i && s[i]->dollared()) { - ret->name = s[i]->str(); - i++; + sName = s[i++]->str(); } else { - ret->name = getPrefixedName("loop-in"); + sName = "loop-in"; } + ret->name = nameMapper.pushLabelName(sName); ret->type = none; if (i < s.size() && s[i]->isStr()) { // block signature ret->type = stringToWasmType(s[i++]->str()); } - labelStack.push_back(ret->name); ret->body = makeMaybeBlock(s, i, ret->type); - labelStack.pop_back(); + nameMapper.popLabelName(ret->name); ret->finalize(ret->type); - if (out.is()) { - auto* block = allocator.alloc<Block>(); - block->name = out; - block->list.push_back(ret); - block->finalize(); - return block; - } return ret; } @@ -1367,17 +1347,17 @@ private: } Name getLabel(Element& s) { if (s.dollared()) { - return s.str(); + return nameMapper.sourceToUnique(s.str()); } else { // offset, break to nth outside label uint64_t offset = std::stoll(s.c_str(), nullptr, 0); - if (offset > labelStack.size()) throw ParseException("invalid label", s.line, s.col); - if (offset == labelStack.size()) { + if (offset > nameMapper.labelStack.size()) throw ParseException("invalid label", s.line, s.col); + if (offset == nameMapper.labelStack.size()) { // a break to the function's scope. this means we need an automatic block, with a name brokeToAutoBlock = true; return FAKE_RETURN; } - return labelStack[labelStack.size() - 1 - offset]; + return nameMapper.labelStack[nameMapper.labelStack.size() - 1 - offset]; } } Expression* makeBreak(Element& s) { |