diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 685da0bf1..1fb43c884 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1070,6 +1070,30 @@ void WasmBinaryWriter::writeNames() { } } + // tag names + if (!wasm->tags.empty()) { + Index count = 0; + for (auto& tag : wasm->tags) { + if (tag->hasExplicitName) { + count++; + } + } + + if (count) { + auto substart = + startSubsection(BinaryConsts::UserSections::Subsection::NameTag); + o << U32LEB(count); + for (Index i = 0; i < wasm->tags.size(); i++) { + auto& tag = wasm->tags[i]; + if (tag->hasExplicitName) { + o << U32LEB(i); + writeEscapedName(tag->name.str); + } + } + finishSubsection(substart); + } + } + finishSection(start); } @@ -3012,24 +3036,26 @@ void WasmBinaryBuilder::processNames() { *ref = getFunctionName(index); } } - for (auto& [index, refs] : tableRefs) { for (auto* ref : refs) { *ref = getTableName(index); } } - for (auto& [index, refs] : memoryRefs) { for (auto ref : refs) { *ref = getMemoryName(index); } } - for (auto& [index, refs] : globalRefs) { for (auto* ref : refs) { *ref = getGlobalName(index); } } + for (auto& [index, refs] : tagRefs) { + for (auto* ref : refs) { + *ref = getTagName(index); + } + } // Everything now has its proper name. @@ -3455,6 +3481,22 @@ void WasmBinaryBuilder::readNames(size_t payloadLen) { } } } + } else if (nameType == BinaryConsts::UserSections::Subsection::NameTag) { + auto num = getU32LEB(); + NameProcessor processor; + for (size_t i = 0; i < num; i++) { + auto index = getU32LEB(); + auto rawName = getInlineString(); + auto name = processor.process(rawName); + if (index < wasm.tags.size()) { + wasm.tags[index]->setExplicitName(name); + } else { + std::cerr << "warning: tag index out of bounds in name section, " + "tag subsection: " + << std::string(rawName.str) << " at index " + << std::to_string(index) << std::endl; + } + } } else { std::cerr << "warning: unknown name subsection with id " << std::to_string(nameType) << " at " << pos << std::endl; @@ -6652,6 +6694,11 @@ void WasmBinaryBuilder::visitTryOrTryInBlock(Expression*& out) { } }; + // We cannot immediately update tagRefs in the loop below, as catchTags is + // being grown, an so references would get invalidated. Store the indexes + // here, then do that later. + std::vector<Index> tagIndexes; + while (lastSeparator == BinaryConsts::Catch || lastSeparator == BinaryConsts::CatchAll) { if (lastSeparator == BinaryConsts::Catch) { @@ -6659,10 +6706,10 @@ void WasmBinaryBuilder::visitTryOrTryInBlock(Expression*& out) { if (index >= wasm.tags.size()) { throwError("bad tag index"); } + tagIndexes.push_back(index); auto* tag = wasm.tags[index].get(); curr->catchTags.push_back(tag->name); readCatchBody(tag->sig.params); - } else { // catch_all if (curr->hasCatchAll()) { throwError("there should be at most one 'catch_all' clause per try"); @@ -6672,6 +6719,11 @@ void WasmBinaryBuilder::visitTryOrTryInBlock(Expression*& out) { } breakStack.pop_back(); + for (Index i = 0; i < tagIndexes.size(); i++) { + // We don't know the final name yet. + tagRefs[tagIndexes[i]].push_back(&curr->catchTags[i]); + } + if (lastSeparator == BinaryConsts::Delegate) { curr->delegateTarget = getExceptionTargetName(getU32LEB()); } @@ -6768,6 +6820,7 @@ void WasmBinaryBuilder::visitThrow(Throw* curr) { } auto* tag = wasm.tags[index].get(); curr->tag = tag->name; + tagRefs[index].push_back(&curr->tag); // we don't know the final name yet size_t num = tag->sig.params.size(); curr->operands.resize(num); for (size_t i = 0; i < num; i++) { |