Skip to content

Commit

Permalink
wasm-merge: preserve explicit names
Browse files Browse the repository at this point in the history
- only write explicit function names
- when merging modules, the name of types, globals and tags in all
  modules but the first were lost
  • Loading branch information
vouillon committed Apr 3, 2024
1 parent 44459f7 commit e5ba9c2
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 28 deletions.
7 changes: 4 additions & 3 deletions src/ir/module-splitting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,9 @@ void ModuleSplitter::exportImportFunction(Name funcName) {
// Import the function if it is not already imported into the secondary
// module.
if (secondary.getFunctionOrNull(funcName) == nullptr) {
auto func =
Builder::makeFunction(funcName, primary.getFunction(funcName)->type, {});
auto primaryFunc = primary.getFunction(funcName);
auto func = Builder::makeFunction(funcName, primaryFunc->type, {});
func->hasExplicitName = primaryFunc->hasExplicitName;
func->module = config.importNamespace;
func->base = exportName;
secondary.addFunction(std::move(func));
Expand Down Expand Up @@ -542,7 +543,7 @@ void ModuleSplitter::setupTablePatching() {
placeholder->base = std::to_string(index);
placeholder->name = Names::getValidFunctionName(
primary, std::string("placeholder_") + placeholder->base.toString());
placeholder->hasExplicitName = false;
placeholder->hasExplicitName = true;
placeholder->type = secondaryFunc->type;
elem = placeholder->name;
primary.addFunction(std::move(placeholder));
Expand Down
10 changes: 9 additions & 1 deletion src/ir/module-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Function* copyFunction(Function* func,
std::optional<std::vector<Index>> fileIndexMap) {
auto ret = std::make_unique<Function>();
ret->name = newName.is() ? newName : func->name;
ret->hasExplicitName = func->hasExplicitName && !newName.is();
ret->type = func->type;
ret->vars = func->vars;
ret->localNames = func->localNames;
Expand Down Expand Up @@ -77,6 +78,7 @@ Function* copyFunction(Function* func,
Global* copyGlobal(Global* global, Module& out) {
auto* ret = new Global();
ret->name = global->name;
ret->hasExplicitName = global->hasExplicitName;
ret->type = global->type;
ret->mutable_ = global->mutable_;
ret->module = global->module;
Expand All @@ -93,6 +95,7 @@ Global* copyGlobal(Global* global, Module& out) {
Tag* copyTag(Tag* tag, Module& out) {
auto* ret = new Tag();
ret->name = tag->name;
ret->hasExplicitName = tag->hasExplicitName;
ret->sig = tag->sig;
ret->module = tag->module;
ret->base = tag->base;
Expand Down Expand Up @@ -209,6 +212,12 @@ void copyModuleItems(const Module& in, Module& out) {
for (auto& curr : in.dataSegments) {
copyDataSegment(curr.get(), out);
}

for (auto& [type, names] : in.typeNames) {
if (!out.typeNames.count(type)) {
out.typeNames[type] = names;
}
}
}

void copyModule(const Module& in, Module& out) {
Expand All @@ -222,7 +231,6 @@ void copyModule(const Module& in, Module& out) {
out.customSections = in.customSections;
out.debugInfoFileNames = in.debugInfoFileNames;
out.features = in.features;
out.typeNames = in.typeNames;
}

void clearModule(Module& wasm) {
Expand Down
32 changes: 20 additions & 12 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,19 +864,27 @@ void WasmBinaryWriter::writeNames() {

// function names
{
auto substart =
startSubsection(BinaryConsts::CustomSections::Subsection::NameFunction);
o << U32LEB(indexes.functionIndexes.size());
Index emitted = 0;
auto add = [&](Function* curr) {
o << U32LEB(emitted);
writeEscapedName(curr->name.str);
emitted++;
std::vector<std::pair<Index, Function*>> functionsWithNames;
Index checked = 0;
auto check = [&](Function* curr) {
if (curr->hasExplicitName) {
functionsWithNames.push_back({checked, curr});
}
checked++;
};
ModuleUtils::iterImportedFunctions(*wasm, add);
ModuleUtils::iterDefinedFunctions(*wasm, add);
assert(emitted == indexes.functionIndexes.size());
finishSubsection(substart);
ModuleUtils::iterImportedFunctions(*wasm, check);
ModuleUtils::iterDefinedFunctions(*wasm, check);
assert(checked == indexes.functionIndexes.size());
if (functionsWithNames.size() > 0) {
auto substart =
startSubsection(BinaryConsts::CustomSections::Subsection::NameFunction);
o << U32LEB(functionsWithNames.size());
for (auto& [index, global] : functionsWithNames) {
o << U32LEB(index);
writeEscapedName(global->name.str);
}
finishSubsection(substart);
}
}

// local names
Expand Down
1 change: 1 addition & 0 deletions src/wasm/wasm-s-parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
// make a new function
currFunction = std::unique_ptr<Function>(
Builder(wasm).makeFunction(name, std::move(params), type, std::move(vars)));
currFunction->hasExplicitName = hasExplicitName;
currFunction->profile = profile;

// parse body
Expand Down
20 changes: 10 additions & 10 deletions test/lit/merge/names.wat
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

;; CHECK: (type $2 (func (param (ref $t))))

;; CHECK: (type $3 (struct (field i64) (field i32)))
;; CHECK: (type $u (struct (field $c i64) (field $d i32)))

;; CHECK: (type $4 (func (param (ref $3))))
;; CHECK: (type $4 (func (param (ref $u))))

;; CHECK: (global $global$0 i32 (i32.const 0))

;; CHECK: (global $global$1 i32 (i32.const 0))
;; CHECK: (global $glob2 i32 (i32.const 0))

;; CHECK: (global $global$2 i32 (i32.const 0))

Expand All @@ -40,7 +40,7 @@

;; CHECK: (tag $tag$1)

;; CHECK: (tag $tag$2)
;; CHECK: (tag $tag2)

;; CHECK: (tag $tag$3)

Expand Down Expand Up @@ -72,21 +72,21 @@

;; CHECK: (export "f2" (func $func2))

;; CHECK: (export "f3" (func $1_3))
;; CHECK: (export "f3" (func $4))

;; CHECK: (export "t2" (table $table2))

;; CHECK: (export "t3" (table $3))

;; CHECK: (export "g2" (global $global$1))
;; CHECK: (export "g2" (global $glob2))

;; CHECK: (export "g3" (global $global$0))

;; CHECK: (export "tag2" (tag $tag$2))
;; CHECK: (export "tag2" (tag $tag2))

;; CHECK: (export "tag3" (tag $tag$3))

;; CHECK: (export "func2" (func $2_3))
;; CHECK: (export "func2" (func $5))

;; CHECK: (func $func0 (type $0)
;; CHECK-NEXT: (nop)
Expand Down Expand Up @@ -128,10 +128,10 @@
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )

;; CHECK: (func $1_3 (type $0)
;; CHECK: (func $4 (type $0)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )

;; CHECK: (func $2_3 (type $4) (param $0 (ref $3))
;; CHECK: (func $5 (type $4) (param $0 (ref $u))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
4 changes: 2 additions & 2 deletions test/passes/func-metrics.txt
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func: func_a
Block : 1
Call : 5
start: func_a
[removable-bytes-without-it]: 57
[removable-bytes-without-it]: 60
[total] : 0
(module
(type $0 (func))
Expand Down Expand Up @@ -274,7 +274,7 @@ func: 0
[vars] : 0
GlobalGet : 1
export: stackSave (0)
[removable-bytes-without-it]: 62
[removable-bytes-without-it]: 79
[total] : 0
(module
(type $0 (func (result i32)))
Expand Down
Binary file modified test/unit/input/gc_target_feature.wasm
Binary file not shown.

0 comments on commit e5ba9c2

Please sign in to comment.