diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wasm-stack.cpp | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index dda47ffa6..1ed60abed 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2568,25 +2568,45 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { for (Index i = 0; i < func->getNumParams(); i++) { mappedLocals[std::make_pair(i, 0)] = i; } + // Normally we map all locals of the same type into a range of adjacent // addresses, which is more compact. However, if we need to keep DWARF valid, // do not do any reordering at all - instead, do a trivial mapping that // keeps everything unmoved. + // + // Unless we have run DWARF-invalidating passes, all locals added during the + // process that are not in DWARF info (tuple locals, tuple scratch locals, + // locals to resolve stacky format, ..) have been all tacked on to the + // existing locals and happen at the end, so as long as we print the local + // types in order, we don't invalidate original local DWARF info here. if (DWARF) { - FindAll<TupleExtract> extracts(func->body); - if (!extracts.list.empty()) { - Fatal() << "DWARF + multivalue is not yet complete"; + Index mappedIndex = func->getVarIndexBase(); + for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) { + size_t size = func->getLocalType(i).size(); + for (Index j = 0; j < size; j++) { + mappedLocals[std::make_pair(i, j)] = mappedIndex + j; + } + mappedIndex += size; } - Index varStart = func->getVarIndexBase(); - Index varEnd = varStart + func->getNumVars(); - o << U32LEB(func->getNumVars()); - for (Index i = varStart; i < varEnd; i++) { - mappedLocals[std::make_pair(i, 0)] = i; + countScratchLocals(); + + size_t numBinaryLocals = + mappedIndex - func->getVarIndexBase() + scratchLocals.size(); + o << U32LEB(numBinaryLocals); + for (Index i = func->getVarIndexBase(); i < func->getNumLocals(); i++) { + for (const auto& type : func->getLocalType(i)) { + o << U32LEB(1); + parent.writeType(type); + } + } + for (auto& [type, _] : scratchLocals) { o << U32LEB(1); - parent.writeType(func->getLocalType(i)); + parent.writeType(type); + scratchLocals[type] = mappedIndex++; } return; } + for (auto type : func->vars) { for (const auto& t : type) { noteLocalType(t); |