Skip to content

Commit d662d73

Browse files
authored
Fixes regarding explicit names (#6466)
- Only write explicit function names. - When merging modules, the name of types, globals and tags in all modules but the first were lost. - Set name as explicit when copying a function with a new name.
1 parent 729f64c commit d662d73

File tree

8 files changed

+203
-18
lines changed

8 files changed

+203
-18
lines changed

src/ir/module-splitting.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,9 @@ void ModuleSplitter::exportImportFunction(Name funcName) {
395395
// Import the function if it is not already imported into the secondary
396396
// module.
397397
if (secondary.getFunctionOrNull(funcName) == nullptr) {
398-
auto func =
399-
Builder::makeFunction(funcName, primary.getFunction(funcName)->type, {});
398+
auto primaryFunc = primary.getFunction(funcName);
399+
auto func = Builder::makeFunction(funcName, primaryFunc->type, {});
400+
func->hasExplicitName = primaryFunc->hasExplicitName;
400401
func->module = config.importNamespace;
401402
func->base = exportName;
402403
secondary.addFunction(std::move(func));
@@ -542,7 +543,7 @@ void ModuleSplitter::setupTablePatching() {
542543
placeholder->base = std::to_string(index);
543544
placeholder->name = Names::getValidFunctionName(
544545
primary, std::string("placeholder_") + placeholder->base.toString());
545-
placeholder->hasExplicitName = false;
546+
placeholder->hasExplicitName = true;
546547
placeholder->type = secondaryFunc->type;
547548
elem = placeholder->name;
548549
primary.addFunction(std::move(placeholder));

src/ir/module-utils.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Function* copyFunction(Function* func,
4848
std::optional<std::vector<Index>> fileIndexMap) {
4949
auto ret = std::make_unique<Function>();
5050
ret->name = newName.is() ? newName : func->name;
51+
ret->hasExplicitName = func->hasExplicitName;
5152
ret->type = func->type;
5253
ret->vars = func->vars;
5354
ret->localNames = func->localNames;
@@ -77,6 +78,7 @@ Function* copyFunction(Function* func,
7778
Global* copyGlobal(Global* global, Module& out) {
7879
auto* ret = new Global();
7980
ret->name = global->name;
81+
ret->hasExplicitName = global->hasExplicitName;
8082
ret->type = global->type;
8183
ret->mutable_ = global->mutable_;
8284
ret->module = global->module;
@@ -93,6 +95,7 @@ Global* copyGlobal(Global* global, Module& out) {
9395
Tag* copyTag(Tag* tag, Module& out) {
9496
auto* ret = new Tag();
9597
ret->name = tag->name;
98+
ret->hasExplicitName = tag->hasExplicitName;
9699
ret->sig = tag->sig;
97100
ret->module = tag->module;
98101
ret->base = tag->base;
@@ -209,8 +212,17 @@ void copyModuleItems(const Module& in, Module& out) {
209212
for (auto& curr : in.dataSegments) {
210213
copyDataSegment(curr.get(), out);
211214
}
215+
216+
for (auto& [type, names] : in.typeNames) {
217+
if (!out.typeNames.count(type)) {
218+
out.typeNames[type] = names;
219+
}
220+
}
212221
}
213222

223+
// TODO: merge this with copyModuleItems, and add options for copying
224+
// exports and other things that are currently different between them,
225+
// if we still need those differences.
214226
void copyModule(const Module& in, Module& out) {
215227
// we use names throughout, not raw pointers, so simple copying is fine
216228
// for everything *but* expressions
@@ -222,7 +234,6 @@ void copyModule(const Module& in, Module& out) {
222234
out.customSections = in.customSections;
223235
out.debugInfoFileNames = in.debugInfoFileNames;
224236
out.features = in.features;
225-
out.typeNames = in.typeNames;
226237
}
227238

228239
void clearModule(Module& wasm) {

src/wasm/wasm-binary.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -864,19 +864,27 @@ void WasmBinaryWriter::writeNames() {
864864

865865
// function names
866866
{
867-
auto substart =
868-
startSubsection(BinaryConsts::CustomSections::Subsection::NameFunction);
869-
o << U32LEB(indexes.functionIndexes.size());
870-
Index emitted = 0;
871-
auto add = [&](Function* curr) {
872-
o << U32LEB(emitted);
873-
writeEscapedName(curr->name.str);
874-
emitted++;
867+
std::vector<std::pair<Index, Function*>> functionsWithNames;
868+
Index checked = 0;
869+
auto check = [&](Function* curr) {
870+
if (curr->hasExplicitName) {
871+
functionsWithNames.push_back({checked, curr});
872+
}
873+
checked++;
875874
};
876-
ModuleUtils::iterImportedFunctions(*wasm, add);
877-
ModuleUtils::iterDefinedFunctions(*wasm, add);
878-
assert(emitted == indexes.functionIndexes.size());
879-
finishSubsection(substart);
875+
ModuleUtils::iterImportedFunctions(*wasm, check);
876+
ModuleUtils::iterDefinedFunctions(*wasm, check);
877+
assert(checked == indexes.functionIndexes.size());
878+
if (functionsWithNames.size() > 0) {
879+
auto substart =
880+
startSubsection(BinaryConsts::CustomSections::Subsection::NameFunction);
881+
o << U32LEB(functionsWithNames.size());
882+
for (auto& [index, global] : functionsWithNames) {
883+
o << U32LEB(index);
884+
writeEscapedName(global->name.str);
885+
}
886+
finishSubsection(substart);
887+
}
880888
}
881889

882890
// local names

src/wasm/wasm-s-parser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,7 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) {
11811181
// make a new function
11821182
currFunction = std::unique_ptr<Function>(
11831183
Builder(wasm).makeFunction(name, std::move(params), type, std::move(vars)));
1184+
currFunction->hasExplicitName = hasExplicitName;
11841185
currFunction->profile = profile;
11851186

11861187
// parse body

test/lit/merge/names.wat

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
;; RUN: wasm-merge -g %s first %s.second second -all -o %t.wasm
3+
;; RUN: wasm-opt -all %t.wasm -S -o - | filecheck %s
4+
(module
5+
;; CHECK: (type $0 (func))
6+
7+
;; CHECK: (type $t (struct (field $a i32) (field $b i32)))
8+
9+
;; CHECK: (type $2 (func (param (ref $t))))
10+
11+
;; CHECK: (type $u (struct (field $c i64) (field $d i32)))
12+
13+
;; CHECK: (type $4 (func (param (ref $u))))
14+
15+
;; CHECK: (global $global$0 i32 (i32.const 0))
16+
17+
;; CHECK: (global $glob2 i32 (i32.const 0))
18+
19+
;; CHECK: (global $global$2 i32 (i32.const 0))
20+
21+
;; CHECK: (global $glob0 i32 (i32.const 0))
22+
23+
;; CHECK: (memory $mem0 0)
24+
25+
;; CHECK: (memory $1 0)
26+
27+
;; CHECK: (memory $mem2 0)
28+
29+
;; CHECK: (memory $3 0)
30+
31+
;; CHECK: (table $table0 1 funcref)
32+
33+
;; CHECK: (table $1 1 funcref)
34+
35+
;; CHECK: (table $table2 1 funcref)
36+
37+
;; CHECK: (table $3 1 funcref)
38+
39+
;; CHECK: (tag $tag0)
40+
41+
;; CHECK: (tag $tag$1)
42+
43+
;; CHECK: (tag $tag2)
44+
45+
;; CHECK: (tag $tag$3)
46+
47+
;; CHECK: (export "m0" (memory $mem0))
48+
49+
;; CHECK: (export "m1" (memory $1))
50+
51+
;; CHECK: (export "f0" (func $func0))
52+
53+
;; CHECK: (export "f1" (func $1))
54+
55+
;; CHECK: (export "t0" (table $table0))
56+
57+
;; CHECK: (export "t1" (table $1))
58+
59+
;; CHECK: (export "g0" (global $glob0))
60+
61+
;; CHECK: (export "g1" (global $global$2))
62+
63+
;; CHECK: (export "tag0" (tag $tag0))
64+
65+
;; CHECK: (export "tag1" (tag $tag$1))
66+
67+
;; CHECK: (export "func" (func $2))
68+
69+
;; CHECK: (export "m2" (memory $mem2))
70+
71+
;; CHECK: (export "m3" (memory $3))
72+
73+
;; CHECK: (export "f2" (func $func2))
74+
75+
;; CHECK: (export "f3" (func $4))
76+
77+
;; CHECK: (export "t2" (table $table2))
78+
79+
;; CHECK: (export "t3" (table $3))
80+
81+
;; CHECK: (export "g2" (global $glob2))
82+
83+
;; CHECK: (export "g3" (global $global$0))
84+
85+
;; CHECK: (export "tag2" (tag $tag2))
86+
87+
;; CHECK: (export "tag3" (tag $tag$3))
88+
89+
;; CHECK: (export "func2" (func $5))
90+
91+
;; CHECK: (func $func0 (type $0)
92+
;; CHECK-NEXT: (nop)
93+
;; CHECK-NEXT: )
94+
(func $func0 (export "f0"))
95+
(func (export "f1"))
96+
97+
(table $table0 (export "t0") 1 funcref)
98+
(table (export "t1") 1 funcref)
99+
100+
(global $glob0 (export g0) i32 (i32.const 0))
101+
(global (export g1) i32 (i32.const 0))
102+
103+
(memory $mem0 (export "m0") 0)
104+
(memory (export "m1") 0)
105+
106+
(elem $elem0 func)
107+
(elem func)
108+
109+
(data $data0 "")
110+
(data "")
111+
112+
(tag $tag0 (export tag0))
113+
(tag (export tag1))
114+
115+
(type $t (struct (field $a i32) (field $b i32)))
116+
117+
(func (export "func") (param $x (ref $t)))
118+
)
119+
;; CHECK: (func $1 (type $0)
120+
;; CHECK-NEXT: (nop)
121+
;; CHECK-NEXT: )
122+
123+
;; CHECK: (func $2 (type $2) (param $x (ref $t))
124+
;; CHECK-NEXT: (nop)
125+
;; CHECK-NEXT: )
126+
127+
;; CHECK: (func $func2 (type $0)
128+
;; CHECK-NEXT: (nop)
129+
;; CHECK-NEXT: )
130+
131+
;; CHECK: (func $4 (type $0)
132+
;; CHECK-NEXT: (nop)
133+
;; CHECK-NEXT: )
134+
135+
;; CHECK: (func $5 (type $4) (param $0 (ref $u))
136+
;; CHECK-NEXT: (nop)
137+
;; CHECK-NEXT: )

test/lit/merge/names.wat.second

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
(module
2+
3+
(func $func2 (export "f2"))
4+
(func (export "f3"))
5+
6+
(table $table2 (export "t2") 1 funcref)
7+
(table (export "t3") 1 funcref)
8+
9+
(memory $mem2 (export "m2") 0)
10+
(memory (export "m3") 0)
11+
12+
(global $glob2 (export g2) i32 (i32.const 0))
13+
(global (export g3) i32 (i32.const 0))
14+
15+
(elem $elem2 func)
16+
(elem func)
17+
18+
(data $data2 "")
19+
(data "")
20+
21+
(tag $tag2 (export tag2))
22+
(tag (export tag3))
23+
24+
(type $u (struct (field $c i64) (field $d i32)))
25+
26+
(func (export "func2") (param (ref $u)))
27+
)

test/passes/func-metrics.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ func: func_a
244244
Block : 1
245245
Call : 5
246246
start: func_a
247-
[removable-bytes-without-it]: 57
247+
[removable-bytes-without-it]: 60
248248
[total] : 0
249249
(module
250250
(type $0 (func))
@@ -274,7 +274,7 @@ func: 0
274274
[vars] : 0
275275
GlobalGet : 1
276276
export: stackSave (0)
277-
[removable-bytes-without-it]: 62
277+
[removable-bytes-without-it]: 79
278278
[total] : 0
279279
(module
280280
(type $0 (func (result i32)))
-3 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)