Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,14 @@ class WasmBinaryReader {
std::unordered_map<Index, Name> dataNames;
std::unordered_map<Index, Name> 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<Index, Name> functionExportNames;
std::unordered_map<Index, Name> tableExportNames;
std::unordered_map<Index, Name> memoryExportNames;
std::unordered_map<Index, Name> globalExportNames;
std::unordered_map<Index, Name> 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<Name> usedFunctionNames, usedTableNames, usedMemoryNames,
Expand All @@ -1756,6 +1764,7 @@ class WasmBinaryReader {

Result<> readInst();

void readExportNames();
void readExports();

Result<> readLoad(unsigned bytes, bool signed_, Type type);
Expand Down
117 changes: 86 additions & 31 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
Expand Down Expand Up @@ -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<Index, Name>& 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<Name, bool>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -3117,11 +3131,11 @@ void WasmBinaryReader::getResizableLimits(Address& initial,
}

void WasmBinaryReader::addImport(std::unique_ptr<Function> 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());
Expand All @@ -3130,44 +3144,44 @@ void WasmBinaryReader::addImport(std::unique_ptr<Function> func) {
}

void WasmBinaryReader::addImport(std::unique_ptr<Table> 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> 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> 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> 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));
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<Name> names;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
60 changes: 60 additions & 0 deletions test/lit/binary/import-export-fallback-names.wast
Original file line number Diff line number Diff line change
@@ -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))