summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-11-14 15:20:50 -0500
committerGitHub <noreply@github.com>2024-11-14 20:20:50 +0000
commit614fc7d3a01482ec6b8d48e806e2b43524212c06 (patch)
tree5055c235a2abbb59e49d03040dcd6fa6a07fa34e
parent74a910bc298c95856e5bc09fcd2424d08c5df12f (diff)
downloadbinaryen-614fc7d3a01482ec6b8d48e806e2b43524212c06.tar.gz
binaryen-614fc7d3a01482ec6b8d48e806e2b43524212c06.tar.bz2
binaryen-614fc7d3a01482ec6b8d48e806e2b43524212c06.zip
[NFC] Eagerly set local names in binary reader (#7076)
Instead of setting the local names at the end of binary reading, eagerly set them before parsing function bodies. This is NFC now, but will fix a future bug once the binary reader uses IRBuilder. IRBuilder can introduce new scratch locals, and it gives them the names `$scratch`, `$scratch_1`, etc. If the name section includes locals with the same names and we set those local names after parsing function bodies, then we can end up with multiple locals with the same names. Setting the names before parsing the function bodies ensures that IRBuilder will generate different names for the scratch locals. The alternative fix would be to generate fresh names when setting names from the name section, but it is better to respect the names in the name section and use fresh names for the newly introduced scratch locals instead.
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm/wasm-binary.cpp44
2 files changed, 26 insertions, 19 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 67c1dec96..59114cdb8 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1571,6 +1571,7 @@ public:
void readFunctions();
void readVars();
+ void setLocalNames(Function& func, Index i);
void readExports();
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 57a01bb1c..f5bf11206 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1876,25 +1876,6 @@ void WasmBinaryReader::read() {
}
}
- // Set local names for imported and declared functions.
- for (auto& [index, locals] : localNames) {
- if (index >= wasm.functions.size()) {
- std::cerr << "warning: function index out of bounds in name section: "
- "locals at index "
- << index << '\n';
- continue;
- }
- for (auto& [local, name] : locals) {
- if (local >= wasm.functions[index]->getNumLocals()) {
- std::cerr << "warning: local index out of bounds in name section: "
- << name << " at index " << local << " in function " << index
- << '\n';
- continue;
- }
- wasm.functions[index]->setLocalName(local, name);
- }
- }
-
validateBinary();
}
@@ -2626,6 +2607,7 @@ void WasmBinaryReader::readImports() {
curr->hasExplicitName = isExplicit;
curr->module = module;
curr->base = base;
+ setLocalNames(*curr, wasm.functions.size());
wasm.addFunction(std::move(curr));
break;
}
@@ -2728,6 +2710,20 @@ void WasmBinaryReader::requireFunctionContext(const char* error) {
}
}
+void WasmBinaryReader::setLocalNames(Function& func, Index i) {
+ if (auto it = localNames.find(i); it != localNames.end()) {
+ for (auto& [local, name] : it->second) {
+ if (local >= func.getNumLocals()) {
+ std::cerr << "warning: local index out of bounds in name section: "
+ << name << " at index " << local << " in function " << i
+ << '\n';
+ continue;
+ }
+ func.setLocalName(local, name);
+ }
+ }
+}
+
void WasmBinaryReader::readFunctionSignatures() {
size_t num = getU32LEB();
auto numImports = wasm.functions.size();
@@ -2739,6 +2735,15 @@ void WasmBinaryReader::readFunctionSignatures() {
}
usedNames.insert(name);
}
+ // Also check that the function indices in the local names subsection are
+ // in-bounds, even though we don't use them here.
+ for (auto& [index, locals] : localNames) {
+ if (index >= num + numImports) {
+ std::cerr << "warning: function index out of bounds in name section: "
+ "locals at index "
+ << index << '\n';
+ }
+ }
for (size_t i = 0; i < num; i++) {
auto [name, isExplicit] =
getOrMakeName(functionNames, numImports + i, makeName("", i), usedNames);
@@ -2810,6 +2815,7 @@ void WasmBinaryReader::readFunctions() {
readNextDebugLocation();
readVars();
+ setLocalNames(*func, numFuncImports + i);
func->prologLocation = debugLocation;
{