diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-binary.h | 8 | ||||
-rw-r--r-- | src/wasm-stack.h | 14 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 34 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 33 |
4 files changed, 64 insertions, 25 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9f298662b..d490a2a96 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1090,6 +1090,9 @@ enum FeaturePrefix { } // namespace BinaryConsts +// (local index in IR, tuple index) => binary local index +using MappedLocals = std::unordered_map<std::pair<Index, Index>, size_t>; + // Writes out wasm to the binary format class WasmBinaryWriter { @@ -1275,6 +1278,11 @@ private: // the function is written out. std::vector<Expression*> binaryLocationTrackedExpressionsForFunc; + // Maps function names to their mapped locals. This is used when we emit the + // local names section: we map the locals when writing the function, save that + // info here, and then use it when writing the names. + std::unordered_map<Name, MappedLocals> funcMappedLocals; + void prepare(); }; diff --git a/src/wasm-stack.h b/src/wasm-stack.h index 5af9adbce..38b64dff4 100644 --- a/src/wasm-stack.h +++ b/src/wasm-stack.h @@ -118,6 +118,8 @@ public: void emitUnreachable(); void mapLocalsAndEmitHeader(); + MappedLocals mappedLocals; + private: void emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset); int32_t getBreakIndex(Name name); @@ -130,10 +132,12 @@ private: std::vector<Name> breakStack; + // The types of locals in the compact form, in order. + std::vector<Type> localTypes; // type => number of locals of that type in the compact form - std::map<Type, size_t> numLocalsByType; - // (local index, tuple index) => binary local index - std::map<std::pair<Index, Index>, size_t> mappedLocals; + std::unordered_map<Type, size_t> numLocalsByType; + + void noteLocalType(Type type); // Keeps track of the binary index of the scratch locals used to lower // tuple.extract. @@ -401,6 +405,8 @@ public: } } + MappedLocals& getMappedLocals() { return writer.mappedLocals; } + private: WasmBinaryWriter& parent; BinaryInstWriter writer; @@ -458,6 +464,8 @@ public: void write(); + MappedLocals& getMappedLocals() { return writer.mappedLocals; } + private: BinaryInstWriter writer; Function* func; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 0993eb124..0f40cfd58 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -336,10 +336,18 @@ void WasmBinaryWriter::writeFunctions() { // Emit Stack IR if present, and if we can if (func->stackIR && !sourceMap && !DWARF) { BYN_TRACE("write Stack IR\n"); - StackIRToBinaryWriter(*this, o, func).write(); + StackIRToBinaryWriter writer(*this, o, func); + writer.write(); + if (debugInfo) { + funcMappedLocals[func->name] = std::move(writer.getMappedLocals()); + } } else { BYN_TRACE("write Binaryen IR\n"); - BinaryenIRToBinaryWriter(*this, o, func, sourceMap, DWARF).write(); + BinaryenIRToBinaryWriter writer(*this, o, func, sourceMap, DWARF); + writer.write(); + if (debugInfo) { + funcMappedLocals[func->name] = std::move(writer.getMappedLocals()); + } } size_t size = o.size() - start; assert(size <= std::numeric_limits<uint32_t>::max()); @@ -678,20 +686,28 @@ void WasmBinaryWriter::writeNames() { startSubsection(BinaryConsts::UserSections::Subsection::NameLocal); o << U32LEB(functionsWithLocalNames.size()); Index emitted = 0; - for (auto& indexedFunc : functionsWithLocalNames) { + for (auto& kv : functionsWithLocalNames) { + auto index = kv.first; + auto* func = kv.second; + // Pairs of (local index in IR, name). std::vector<std::pair<Index, Name>> localsWithNames; - auto numLocals = indexedFunc.second->getNumLocals(); + auto numLocals = func->getNumLocals(); for (Index i = 0; i < numLocals; ++i) { - if (indexedFunc.second->hasLocalName(i)) { - localsWithNames.push_back({i, indexedFunc.second->getLocalName(i)}); + if (func->hasLocalName(i)) { + localsWithNames.push_back({i, func->getLocalName(i)}); } } assert(localsWithNames.size()); - o << U32LEB(indexedFunc.first); + o << U32LEB(index); o << U32LEB(localsWithNames.size()); for (auto& indexedLocal : localsWithNames) { - o << U32LEB(indexedLocal.first); - writeEscapedName(indexedLocal.second.str); + auto indexInFunc = indexedLocal.first; + auto name = indexedLocal.second; + // TODO: handle multivalue + auto indexInBinary = + funcMappedLocals.at(func->name)[{indexInFunc, 0}]; + o << U32LEB(indexInBinary); + writeEscapedName(name.str); } emitted++; } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 4c4e4e9d1..0c7448c58 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2166,7 +2166,7 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { } for (auto type : func->vars) { for (const auto& t : type) { - numLocalsByType[t]++; + noteLocalType(t); } } countScratchLocals(); @@ -2176,24 +2176,31 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() { for (const auto& type : func->getLocalType(i)) { auto fullIndex = std::make_pair(i, j++); Index index = func->getVarIndexBase(); - for (auto& typeCount : numLocalsByType) { - if (type == typeCount.first) { - mappedLocals[fullIndex] = index + currLocalsByType[typeCount.first]; + for (auto& localType : localTypes) { + if (type == localType) { + mappedLocals[fullIndex] = index + currLocalsByType[localType]; currLocalsByType[type]++; break; } - index += typeCount.second; + index += numLocalsByType.at(localType); } } } setScratchLocals(); o << U32LEB(numLocalsByType.size()); - for (auto& typeCount : numLocalsByType) { - o << U32LEB(typeCount.second); - parent.writeType(typeCount.first); + for (auto& localType : localTypes) { + o << U32LEB(numLocalsByType.at(localType)); + parent.writeType(localType); } } +void BinaryInstWriter::noteLocalType(Type type) { + if (!numLocalsByType.count(type)) { + localTypes.push_back(type); + } + numLocalsByType[type]++; +} + void BinaryInstWriter::countScratchLocals() { // Add a scratch register in `numLocalsByType` for each type of // tuple.extract with nonzero index present. @@ -2204,16 +2211,16 @@ void BinaryInstWriter::countScratchLocals() { } } for (auto t : scratchLocals) { - numLocalsByType[t.first]++; + noteLocalType(t.first); } } void BinaryInstWriter::setScratchLocals() { Index index = func->getVarIndexBase(); - for (auto& typeCount : numLocalsByType) { - index += typeCount.second; - if (scratchLocals.find(typeCount.first) != scratchLocals.end()) { - scratchLocals[typeCount.first] = index - 1; + for (auto& localType : localTypes) { + index += numLocalsByType[localType]; + if (scratchLocals.find(localType) != scratchLocals.end()) { + scratchLocals[localType] = index - 1; } } } |