From 236b188b9627c31e80be8a9a22aa92cff5a78824 Mon Sep 17 00:00:00 2001 From: Govind Yadav Date: Sun, 6 Sep 2026 10:36:21 +0530 Subject: [PATCH] Improve fallback names for imported and exported items --- src/wasm-binary.h | 9 ++ src/wasm/wasm-binary.cpp | 117 +++++++++++++----- .../binary/import-export-fallback-names.wast | 60 +++++++++ 3 files changed, 155 insertions(+), 31 deletions(-) create mode 100644 test/lit/binary/import-export-fallback-names.wast diff --git a/src/wasm-binary.h b/src/wasm-binary.h index eb53aab8703..df7bd13a063 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1737,6 +1737,14 @@ class WasmBinaryReader { std::unordered_map dataNames; std::unordered_map elemNames; + // When there is no explicit name section entry, use external names from + // exports as more meaningful fallbacks than generated numeric names. + std::unordered_map functionExportNames; + std::unordered_map tableExportNames; + std::unordered_map memoryExportNames; + std::unordered_map globalExportNames; + std::unordered_map tagExportNames; + // The names that are already used (either from the names section, or that we // generate as internal names for un-named things). std::unordered_set usedFunctionNames, usedTableNames, usedMemoryNames, @@ -1756,6 +1764,7 @@ class WasmBinaryReader { Result<> readInst(); + void readExportNames(); void readExports(); Result<> readLoad(unsigned bytes, bool signed_, Type type); diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 746ddbc339f..ceeb3380590 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2200,7 +2200,9 @@ void WasmBinaryReader::preScan() { throwError("Section extends beyond end of input"); } auto oldPos = pos; - if (sectionCode == BinaryConsts::Section::Custom) { + if (sectionCode == BinaryConsts::Section::Export) { + readExportNames(); + } else if (sectionCode == BinaryConsts::Section::Custom) { auto sectionName = getInlineString(); if (sectionName == Annotations::BranchHint || @@ -2749,6 +2751,15 @@ static Name makeName(std::string prefix, size_t counter) { return Name(prefix + std::to_string(counter)); } +static Name getFallbackName(const std::unordered_map& nameMap, + Index i, + Name fallback) { + if (auto it = nameMap.find(i); it != nameMap.end()) { + return it->second; + } + return fallback; +} + // Look up a name from the names section or use a validated version of the // provided name. Return the name and whether it is explicit in the input. static std::pair @@ -2776,7 +2787,10 @@ void WasmBinaryReader::readMemories() { } for (size_t i = 0; i < num; i++) { auto [name, isExplicit] = getOrMakeName( - memoryNames, numImports + i, makeName("", i), usedMemoryNames); + memoryNames, + numImports + i, + getFallbackName(memoryExportNames, numImports + i, makeName("", i)), + usedMemoryNames); auto memory = Builder::makeMemory(name); memory->hasExplicitName = isExplicit; getResizableLimits(memory->initial, @@ -3117,11 +3131,11 @@ void WasmBinaryReader::getResizableLimits(Address& initial, } void WasmBinaryReader::addImport(std::unique_ptr func) { - auto [name, isExplicit] = - getOrMakeName(functionNames, - wasm.functions.size(), - makeName("fimport$", wasm.functions.size()), - usedFunctionNames); + auto [name, isExplicit] = getOrMakeName( + functionNames, + wasm.functions.size(), + func->base ? func->base : makeName("fimport$", wasm.functions.size()), + usedFunctionNames); func->name = name; func->hasExplicitName = isExplicit; functionTypes.push_back(func->type.getHeapType()); @@ -3130,44 +3144,44 @@ void WasmBinaryReader::addImport(std::unique_ptr func) { } void WasmBinaryReader::addImport(std::unique_ptr table) { - auto [name, isExplicit] = - getOrMakeName(tableNames, - wasm.tables.size(), - makeName("timport$", wasm.tables.size()), - usedTableNames); + auto [name, isExplicit] = getOrMakeName( + tableNames, + wasm.tables.size(), + table->base ? table->base : makeName("timport$", wasm.tables.size()), + usedTableNames); table->name = name; table->hasExplicitName = isExplicit; wasm.addTable(std::move(table)); } void WasmBinaryReader::addImport(std::unique_ptr memory) { - auto [name, isExplicit] = - getOrMakeName(memoryNames, - wasm.memories.size(), - makeName("mimport$", wasm.memories.size()), - usedMemoryNames); + auto [name, isExplicit] = getOrMakeName( + memoryNames, + wasm.memories.size(), + memory->base ? memory->base : makeName("mimport$", wasm.memories.size()), + usedMemoryNames); memory->name = name; memory->hasExplicitName = isExplicit; wasm.addMemory(std::move(memory)); } void WasmBinaryReader::addImport(std::unique_ptr global) { - auto [name, isExplicit] = - getOrMakeName(globalNames, - wasm.globals.size(), - makeName("gimport$", wasm.globals.size()), - usedGlobalNames); + auto [name, isExplicit] = getOrMakeName( + globalNames, + wasm.globals.size(), + global->base ? global->base : makeName("gimport$", wasm.globals.size()), + usedGlobalNames); global->name = name; global->hasExplicitName = isExplicit; wasm.addGlobal(std::move(global)); } void WasmBinaryReader::addImport(std::unique_ptr tag) { - auto [name, isExplicit] = - getOrMakeName(tagNames, - wasm.tags.size(), - makeName("eimport$", wasm.tags.size()), - usedTagNames); + auto [name, isExplicit] = getOrMakeName( + tagNames, + wasm.tags.size(), + tag->base ? tag->base : makeName("eimport$", wasm.tags.size()), + usedTagNames); tag->name = name; tag->hasExplicitName = isExplicit; wasm.addTag(std::move(tag)); @@ -3378,7 +3392,10 @@ void WasmBinaryReader::readFunctionSignatures() { } for (size_t i = 0; i < num; i++) { auto [name, isExplicit] = getOrMakeName( - functionNames, numImports + i, makeName("", i), usedFunctionNames); + functionNames, + numImports + i, + getFallbackName(functionExportNames, numImports + i, makeName("", i)), + usedFunctionNames); auto index = getU32LEB(); HeapType type = getTypeByIndex(index); functionTypes.push_back(type); @@ -5079,6 +5096,34 @@ Result<> WasmBinaryReader::readInst() { return Err{"unknown operation " + std::to_string(code)}; } +void WasmBinaryReader::readExportNames() { + auto num = getU32LEB(); + for (size_t i = 0; i < num; i++) { + auto name = getInlineString(); + auto kind = getU32LEB(); + auto index = getU32LEB(); + switch (kind) { + case ExternalKind::Function: + functionExportNames.try_emplace(index, name); + break; + case ExternalKind::Table: + tableExportNames.try_emplace(index, name); + break; + case ExternalKind::Memory: + memoryExportNames.try_emplace(index, name); + break; + case ExternalKind::Global: + globalExportNames.try_emplace(index, name); + break; + case ExternalKind::Tag: + tagExportNames.try_emplace(index, name); + break; + default: + break; + } + } +} + void WasmBinaryReader::readExports() { size_t num = getU32LEB(); std::unordered_set names; @@ -5172,7 +5217,11 @@ void WasmBinaryReader::readGlobals() { } for (size_t i = 0; i < num; i++) { auto [name, isExplicit] = getOrMakeName( - globalNames, numImports + i, makeName("global$", i), usedGlobalNames); + globalNames, + numImports + i, + getFallbackName( + globalExportNames, numImports + i, makeName("global$", i)), + usedGlobalNames); auto type = getConcreteType(); auto mutable_ = getU32LEB(); if (mutable_ & ~1) { @@ -5268,7 +5317,10 @@ void WasmBinaryReader::readTableDeclarations() { } for (size_t i = 0; i < num; i++) { auto [name, isExplicit] = getOrMakeName( - tableNames, numImports + i, makeName("", i), usedTableNames); + tableNames, + numImports + i, + getFallbackName(tableExportNames, numImports + i, makeName("", i)), + usedTableNames); bool hasInit = false; if (peekInt8() == BinaryConsts::HasTableInitializer) { // Skip past the peeked byte. @@ -5403,7 +5455,10 @@ void WasmBinaryReader::readTags() { for (size_t i = 0; i < num; i++) { getInt8(); // Reserved 'attribute' field auto [name, isExplicit] = getOrMakeName( - tagNames, numImports + i, makeName("tag$", i), usedTagNames); + tagNames, + numImports + i, + getFallbackName(tagExportNames, numImports + i, makeName("tag$", i)), + usedTagNames); auto typeIndex = getU32LEB(); auto tag = Builder::makeTag(name, getSignatureByTypeIndex(typeIndex)); tag->hasExplicitName = isExplicit; diff --git a/test/lit/binary/import-export-fallback-names.wast b/test/lit/binary/import-export-fallback-names.wast new file mode 100644 index 00000000000..2a85180a6ad --- /dev/null +++ b/test/lit/binary/import-export-fallback-names.wast @@ -0,0 +1,60 @@ +;; RUN: wasm-as %s --all-features -o %t.wasm +;; RUN: wasm-dis %t.wasm --all-features -o - | filecheck %s --check-prefix=FALLBACK +;; RUN: wasm-as %s --all-features -g -o %t.names.wasm +;; RUN: wasm-dis %t.names.wasm --all-features -o - | filecheck %s --check-prefix=EXPLICIT + +;; Without a name section, use import and export names for internal names. +;; Explicit names from a name section continue to take priority. + +(module + (type $tag_type (func)) + (import "env" "import_func" (func $internal_import_func)) + (import "other" "import_func" (func $internal_second_import_func)) + (import "env" "import_table" (table $internal_import_table 1 funcref)) + (import "env" "import_memory" (memory $internal_import_memory 1)) + (import "env" "import_global" (global $internal_import_global i32)) + (import "env" "import_tag" (tag $internal_import_tag (type $tag_type))) + (func $internal_export_func + (export "export_func") + (export "second_export_func") + ) + (table $internal_export_table (export "export_table") 1 funcref) + (memory $internal_export_memory (export "export_memory") 1) + (global $internal_export_global (export "export_global") i32 (i32.const 0)) + (tag $internal_export_tag (export "export_tag") (type $tag_type)) +) + +;; FALLBACK: (import "env" "import_memory" (memory $import_memory +;; FALLBACK: (import "env" "import_table" (table $import_table +;; FALLBACK: (import "env" "import_global" (global $import_global +;; FALLBACK: (import "env" "import_func" (func $import_func +;; FALLBACK: (import "other" "import_func" (func $import_func_1 +;; FALLBACK: (import "env" "import_tag" (tag $import_tag +;; FALLBACK: (global $export_global +;; FALLBACK: (memory $export_memory +;; FALLBACK: (table $export_table +;; FALLBACK: (tag $export_tag +;; FALLBACK: (export "export_func" (func $export_func)) +;; FALLBACK: (export "second_export_func" (func $export_func)) +;; FALLBACK: (export "export_table" (table $export_table)) +;; FALLBACK: (export "export_memory" (memory $export_memory)) +;; FALLBACK: (export "export_global" (global $export_global)) +;; FALLBACK: (export "export_tag" (tag $export_tag)) +;; FALLBACK: (func $export_func + +;; EXPLICIT: (import "env" "import_memory" (memory $internal_import_memory +;; EXPLICIT: (import "env" "import_table" (table $internal_import_table +;; EXPLICIT: (import "env" "import_global" (global $internal_import_global +;; EXPLICIT: (import "env" "import_func" (func $internal_import_func +;; EXPLICIT: (import "other" "import_func" (func $internal_second_import_func +;; EXPLICIT: (import "env" "import_tag" (tag $internal_import_tag +;; EXPLICIT: (global $internal_export_global +;; EXPLICIT: (memory $internal_export_memory +;; EXPLICIT: (table $internal_export_table +;; EXPLICIT: (tag $internal_export_tag +;; EXPLICIT: (export "export_func" (func $internal_export_func)) +;; EXPLICIT: (export "second_export_func" (func $internal_export_func)) +;; EXPLICIT: (export "export_table" (table $internal_export_table)) +;; EXPLICIT: (export "export_memory" (memory $internal_export_memory)) +;; EXPLICIT: (export "export_global" (global $internal_export_global)) +;; EXPLICIT: (export "export_tag" (tag $internal_export_tag))