diff options
author | Heejin Ahn <aheejin@gmail.com> | 2024-05-06 16:37:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-06 16:37:32 -0700 |
commit | 4b7c610f14329dfe045534ec1cde7f28330393f9 (patch) | |
tree | 4c94816f122ab7655af038c9b9f62af36d7192ad /src/wasm/wasm-stack.cpp | |
parent | d58c54643eb97e5c35f8c14a38f3bf549aee92f4 (diff) | |
download | binaryen-4b7c610f14329dfe045534ec1cde7f28330393f9.tar.gz binaryen-4b7c610f14329dfe045534ec1cde7f28330393f9.tar.bz2 binaryen-4b7c610f14329dfe045534ec1cde7f28330393f9.zip |
Allow DWARF and multivalue together (#6570)
This allows writing of binaries with DWARF info when multivalue is
enabled. Currently we just crash when both are enabled together. This
just assumes, unless we have run DWARF-invalidating passes, all locals
added for tuples or scratch locals would have been added at the end of
the local list, so just printing all locals in order would preserve the
DWARF info. Tuple locals are expanded in place and scratch locals are
added at the end.
Diffstat (limited to 'src/wasm/wasm-stack.cpp')
-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); |