Skip to content

Commit 6d886dc

Browse files
authored
[wasm-split] Escape names in manifest files (#7898)
Functions in languages like C++ have unallowed characters such as parentheses or whitespaces within their names, so if we put them in the manifest files they will not be matched with escaped names we use within Binaryen. This _escapes_ function names when we read them from manifest files.
1 parent 9704e14 commit 6d886dc

File tree

3 files changed

+238
-13
lines changed

3 files changed

+238
-13
lines changed

src/tools/wasm-split/wasm-split.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -390,14 +390,14 @@ void multiSplitModule(const WasmSplitOptions& options) {
390390
parseInput(wasm, options);
391391

392392
// Map module names to the functions that should be in the modules.
393-
std::map<std::string, std::unordered_set<std::string>> moduleFuncs;
393+
std::map<Name, std::unordered_set<Name>> moduleFuncs;
394394
// The module for which we are currently parsing a set of functions.
395-
std::string currModule;
395+
Name currModule;
396396
// The set of functions we are currently inserting into.
397-
std::unordered_set<std::string>* currFuncs = nullptr;
397+
std::unordered_set<Name>* currFuncs = nullptr;
398398
// Map functions to their modules to ensure no function is assigned to
399399
// multiple modules.
400-
std::unordered_map<std::string, std::string> funcModules;
400+
std::unordered_map<Name, Name> funcModules;
401401

402402
std::string line;
403403
bool newSection = true;
@@ -406,22 +406,23 @@ void multiSplitModule(const WasmSplitOptions& options) {
406406
newSection = true;
407407
continue;
408408
}
409+
Name name = WasmBinaryReader::escape(line);
409410
if (newSection) {
410-
currModule = line;
411-
currFuncs = &moduleFuncs[line];
411+
currModule = name;
412+
currFuncs = &moduleFuncs[name];
412413
newSection = false;
413414
continue;
414415
}
415416
assert(currFuncs);
416-
currFuncs->insert(line);
417-
auto [it, inserted] = funcModules.insert({line, currModule});
417+
currFuncs->insert(name);
418+
auto [it, inserted] = funcModules.insert({name, currModule});
418419
if (!inserted && it->second != currModule) {
419-
Fatal() << "Function " << line << "cannot be assigned to module "
420+
Fatal() << "Function " << name << "cannot be assigned to module "
420421
<< currModule << "; it is already assigned to module "
421422
<< it->second << '\n';
422423
}
423-
if (inserted && !options.quiet && !wasm.getFunctionOrNull(line)) {
424-
std::cerr << "warning: Function " << line << " does not exist\n";
424+
if (inserted && !options.quiet && !wasm.getFunctionOrNull(name)) {
425+
std::cerr << "warning: Function " << name << " does not exist\n";
425426
}
426427
}
427428

@@ -443,8 +444,8 @@ void multiSplitModule(const WasmSplitOptions& options) {
443444
}
444445
config.secondaryFuncs = std::set<Name>(funcs.begin(), funcs.end());
445446
auto splitResults = ModuleSplitting::splitFunctions(wasm, config);
446-
auto moduleName =
447-
options.outPrefix + mod + (options.emitBinary ? ".wasm" : ".wast");
447+
auto moduleName = options.outPrefix + mod.toString() +
448+
(options.emitBinary ? ".wasm" : ".wast");
448449
if (options.symbolMap) {
449450
writeSymbolMap(*splitResults.secondary, moduleName + ".symbols");
450451
}
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
3+
;; RUN: wasm-split -all -g --multi-split %s --manifest %s.manifest --out-prefix=%t -o %t.wasm
4+
;; RUN: wasm-dis %t.wasm | filecheck %s --check-prefix=PRIMARY
5+
;; RUN: wasm-dis %t1.wasm | filecheck %s --check-prefix=MOD1
6+
;; RUN: wasm-dis %t2.wasm | filecheck %s --check-prefix=MOD2
7+
;; RUN: wasm-dis %t3.wasm | filecheck %s --check-prefix=MOD3
8+
9+
(module
10+
;; PRIMARY: (type $ret-i32 (func (result i32)))
11+
(type $ret-i32 (func (result i32)))
12+
;; PRIMARY: (type $ret-i64 (func (result i64)))
13+
(type $ret-i64 (func (result i64)))
14+
;; PRIMARY: (type $ret-f32 (func (result f32)))
15+
(type $ret-f32 (func (result f32)))
16+
17+
;; MOD1: (type $0 (func (result f32)))
18+
19+
;; MOD1: (type $1 (func (result i64)))
20+
21+
;; MOD1: (type $2 (func (result i32)))
22+
23+
;; MOD1: (import "" "table" (table $timport$0 1 funcref))
24+
25+
;; MOD1: (import "" "std::operator<<\\28std::__2::basic_ostream<char\\2c\\20std::__2::char_traits<char>>&\\2c\\20wasm::Module&\\29" (func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29 (result f32)))
26+
27+
;; MOD1: (import "" "wasm::Literal::Literal\\28std::__2::array<wasm::Literal\\2c\\204ul>\\20const&\\29" (func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29 (result i64)))
28+
29+
;; MOD1: (elem $0 (i32.const 0) $wasm::Type::getFeatures\28\29\20const)
30+
31+
;; MOD1: (func $wasm::Type::getFeatures\28\29\20const (result i32)
32+
;; MOD1-NEXT: (drop
33+
;; MOD1-NEXT: (call_ref $2
34+
;; MOD1-NEXT: (ref.func $wasm::Type::getFeatures\28\29\20const)
35+
;; MOD1-NEXT: )
36+
;; MOD1-NEXT: )
37+
;; MOD1-NEXT: (drop
38+
;; MOD1-NEXT: (call_ref $1
39+
;; MOD1-NEXT: (ref.func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
40+
;; MOD1-NEXT: )
41+
;; MOD1-NEXT: )
42+
;; MOD1-NEXT: (drop
43+
;; MOD1-NEXT: (call_ref $0
44+
;; MOD1-NEXT: (ref.func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
45+
;; MOD1-NEXT: )
46+
;; MOD1-NEXT: )
47+
;; MOD1-NEXT: (i32.const 0)
48+
;; MOD1-NEXT: )
49+
(func $wasm::Type::getFeatures\28\29\20const (type $ret-i32) (result i32)
50+
(drop
51+
(call_ref $ret-i32
52+
(ref.func $wasm::Type::getFeatures\28\29\20const)
53+
)
54+
)
55+
(drop
56+
(call_ref $ret-i64
57+
(ref.func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
58+
)
59+
)
60+
(drop
61+
(call_ref $ret-f32
62+
(ref.func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
63+
)
64+
)
65+
(i32.const 0)
66+
)
67+
68+
;; MOD2: (type $0 (func (result f32)))
69+
70+
;; MOD2: (type $1 (func (result i32)))
71+
72+
;; MOD2: (type $2 (func (result i64)))
73+
74+
;; MOD2: (import "" "table_4" (table $timport$0 1 funcref))
75+
76+
;; MOD2: (import "" "std::operator<<\\28std::__2::basic_ostream<char\\2c\\20std::__2::char_traits<char>>&\\2c\\20wasm::Module&\\29" (func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29 (result f32)))
77+
78+
;; MOD2: (import "" "trampoline_wasm::Type::getFeatures\\28\\29\\20const" (func $trampoline_wasm::Type::getFeatures\28\29\20const (result i32)))
79+
80+
;; MOD2: (elem $0 (i32.const 0) $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
81+
82+
;; MOD2: (func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29 (result i64)
83+
;; MOD2-NEXT: (drop
84+
;; MOD2-NEXT: (call_ref $1
85+
;; MOD2-NEXT: (ref.func $trampoline_wasm::Type::getFeatures\28\29\20const)
86+
;; MOD2-NEXT: )
87+
;; MOD2-NEXT: )
88+
;; MOD2-NEXT: (drop
89+
;; MOD2-NEXT: (call_ref $2
90+
;; MOD2-NEXT: (ref.func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
91+
;; MOD2-NEXT: )
92+
;; MOD2-NEXT: )
93+
;; MOD2-NEXT: (drop
94+
;; MOD2-NEXT: (call_ref $0
95+
;; MOD2-NEXT: (ref.func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
96+
;; MOD2-NEXT: )
97+
;; MOD2-NEXT: )
98+
;; MOD2-NEXT: (i64.const 0)
99+
;; MOD2-NEXT: )
100+
(func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29 (type $ret-i64) (result i64)
101+
(drop
102+
(call_ref $ret-i32
103+
(ref.func $wasm::Type::getFeatures\28\29\20const)
104+
)
105+
)
106+
(drop
107+
(call_ref $ret-i64
108+
(ref.func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
109+
)
110+
)
111+
(drop
112+
(call_ref $ret-f32
113+
(ref.func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
114+
)
115+
)
116+
(i64.const 0)
117+
)
118+
119+
;; MOD3: (type $0 (func (result i64)))
120+
121+
;; MOD3: (type $1 (func (result i32)))
122+
123+
;; MOD3: (type $2 (func (result f32)))
124+
125+
;; MOD3: (import "" "table_5" (table $timport$0 1 funcref))
126+
127+
;; MOD3: (import "" "wasm::Literal::Literal\\28std::__2::array<wasm::Literal\\2c\\204ul>\\20const&\\29" (func $trampoline_wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29 (result i64)))
128+
129+
;; MOD3: (import "" "trampoline_wasm::Type::getFeatures\\28\\29\\20const" (func $trampoline_wasm::Type::getFeatures\28\29\20const (result i32)))
130+
131+
;; MOD3: (elem $0 (i32.const 0) $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
132+
133+
;; MOD3: (func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29 (result f32)
134+
;; MOD3-NEXT: (drop
135+
;; MOD3-NEXT: (call_ref $1
136+
;; MOD3-NEXT: (ref.func $trampoline_wasm::Type::getFeatures\28\29\20const)
137+
;; MOD3-NEXT: )
138+
;; MOD3-NEXT: )
139+
;; MOD3-NEXT: (drop
140+
;; MOD3-NEXT: (call_ref $0
141+
;; MOD3-NEXT: (ref.func $trampoline_wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
142+
;; MOD3-NEXT: )
143+
;; MOD3-NEXT: )
144+
;; MOD3-NEXT: (drop
145+
;; MOD3-NEXT: (call_ref $2
146+
;; MOD3-NEXT: (ref.func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
147+
;; MOD3-NEXT: )
148+
;; MOD3-NEXT: )
149+
;; MOD3-NEXT: (f32.const 0)
150+
;; MOD3-NEXT: )
151+
(func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29 (type $ret-f32) (result f32)
152+
(drop
153+
(call_ref $ret-i32
154+
(ref.func $wasm::Type::getFeatures\28\29\20const)
155+
)
156+
)
157+
(drop
158+
(call_ref $ret-i64
159+
(ref.func $wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29)
160+
)
161+
)
162+
(drop
163+
(call_ref $ret-f32
164+
(ref.func $std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29)
165+
)
166+
)
167+
(f32.const 0)
168+
)
169+
)
170+
;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (result i32)))
171+
172+
;; PRIMARY: (import "placeholder" "0" (func $placeholder_0_4 (result i64)))
173+
174+
;; PRIMARY: (import "placeholder" "0" (func $placeholder_0_5 (result f32)))
175+
176+
;; PRIMARY: (table $0 1 funcref)
177+
178+
;; PRIMARY: (table $1 1 funcref)
179+
180+
;; PRIMARY: (table $2 1 funcref)
181+
182+
;; PRIMARY: (elem $0 (table $0) (i32.const 0) func $placeholder_0)
183+
184+
;; PRIMARY: (elem $1 (table $1) (i32.const 0) func $placeholder_0_4)
185+
186+
;; PRIMARY: (elem $2 (table $2) (i32.const 0) func $placeholder_0_5)
187+
188+
;; PRIMARY: (export "std::operator<<\\28std::__2::basic_ostream<char\\2c\\20std::__2::char_traits<char>>&\\2c\\20wasm::Module&\\29" (func $trampoline_std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29))
189+
190+
;; PRIMARY: (export "wasm::Literal::Literal\\28std::__2::array<wasm::Literal\\2c\\204ul>\\20const&\\29" (func $trampoline_wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29))
191+
192+
;; PRIMARY: (export "table" (table $0))
193+
194+
;; PRIMARY: (export "trampoline_wasm::Type::getFeatures\\28\\29\\20const" (func $trampoline_wasm::Type::getFeatures\28\29\20const))
195+
196+
;; PRIMARY: (export "table_4" (table $1))
197+
198+
;; PRIMARY: (export "table_5" (table $2))
199+
200+
;; PRIMARY: (func $trampoline_wasm::Type::getFeatures\28\29\20const (result i32)
201+
;; PRIMARY-NEXT: (call_indirect (type $ret-i32)
202+
;; PRIMARY-NEXT: (i32.const 0)
203+
;; PRIMARY-NEXT: )
204+
;; PRIMARY-NEXT: )
205+
206+
;; PRIMARY: (func $trampoline_wasm::Literal::Literal\28std::__2::array<wasm::Literal\2c\204ul>\20const&\29 (result i64)
207+
;; PRIMARY-NEXT: (call_indirect $1 (type $ret-i64)
208+
;; PRIMARY-NEXT: (i32.const 0)
209+
;; PRIMARY-NEXT: )
210+
;; PRIMARY-NEXT: )
211+
212+
;; PRIMARY: (func $trampoline_std::operator<<\28std::__2::basic_ostream<char\2c\20std::__2::char_traits<char>>&\2c\20wasm::Module&\29 (result f32)
213+
;; PRIMARY-NEXT: (call_indirect $2 (type $ret-f32)
214+
;; PRIMARY-NEXT: (i32.const 0)
215+
;; PRIMARY-NEXT: )
216+
;; PRIMARY-NEXT: )
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
1
2+
wasm::Type::getFeatures() const
3+
4+
2
5+
wasm::Literal::Literal(std::__2::array<wasm::Literal, 4ul> const&)
6+
7+
3
8+
std::operator<<(std::__2::basic_ostream<char, std::__2::char_traits<char>>&, wasm::Module&)

0 commit comments

Comments
 (0)