Skip to content

Commit 5602876

Browse files
authored
[Strings] Be stricter when checking builtin types (#7829)
String builtins should not only have the expected signatures, they should also have the expected types. For example, if a builtin has a signature that is in a nontrivial rec group or has a supertype or is not final, that should be a validation error. Reject such incorrect types in StringLifting.
1 parent fe461a4 commit 5602876

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

src/passes/StringLifting.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -131,66 +131,64 @@ struct StringLifting : public Pass {
131131
if (!func->imported() || func->module != WasmStringsModule) {
132132
continue;
133133
}
134-
auto sig = func->type.getSignature();
134+
auto type = func->type;
135135
if (func->base == "fromCharCodeArray") {
136-
if (sig != Signature({array16, i32, i32}, refExtern)) {
137-
Fatal() << "StringLifting: bad signature for fromCharCodeArray: "
138-
<< sig;
136+
if (type != Signature({array16, i32, i32}, refExtern)) {
137+
Fatal() << "StringLifting: bad type for fromCharCodeArray: " << type;
139138
}
140139
fromCharCodeArrayImport = func->name;
141140
found = true;
142141
} else if (func->base == "fromCodePoint") {
143-
if (sig != Signature(i32, refExtern)) {
144-
Fatal() << "StringLifting: bad signature for fromCodePoint: " << sig;
142+
if (type != Signature(i32, refExtern)) {
143+
Fatal() << "StringLifting: bad type for fromCodePoint: " << type;
145144
}
146145
fromCodePointImport = func->name;
147146
found = true;
148147
} else if (func->base == "concat") {
149-
if (sig != Signature({externref, externref}, refExtern)) {
150-
Fatal() << "StringLifting: bad signature for concta: " << sig;
148+
if (type != Signature({externref, externref}, refExtern)) {
149+
Fatal() << "StringLifting: bad type for concat: " << type;
151150
}
152151
concatImport = func->name;
153152
found = true;
154153
} else if (func->base == "intoCharCodeArray") {
155-
if (sig != Signature({externref, array16, i32}, i32)) {
156-
Fatal() << "StringLifting: bad signature for intoCharCodeArray: "
157-
<< sig;
154+
if (type != Signature({externref, array16, i32}, i32)) {
155+
Fatal() << "StringLifting: bad type for intoCharCodeArray: " << type;
158156
}
159157
intoCharCodeArrayImport = func->name;
160158
found = true;
161159
} else if (func->base == "equals") {
162-
if (sig != Signature({externref, externref}, i32)) {
163-
Fatal() << "StringLifting: bad signature for equals: " << sig;
160+
if (type != Signature({externref, externref}, i32)) {
161+
Fatal() << "StringLifting: bad type for equals: " << type;
164162
}
165163
equalsImport = func->name;
166164
found = true;
167165
} else if (func->base == "test") {
168-
if (sig != Signature({externref}, i32)) {
169-
Fatal() << "StringLifting: bad signature for test: " << sig;
166+
if (type != Signature({externref}, i32)) {
167+
Fatal() << "StringLifting: bad type for test: " << type;
170168
}
171169
testImport = func->name;
172170
found = true;
173171
} else if (func->base == "compare") {
174-
if (sig != Signature({externref, externref}, i32)) {
175-
Fatal() << "StringLifting: bad signature for compare: " << sig;
172+
if (type != Signature({externref, externref}, i32)) {
173+
Fatal() << "StringLifting: bad type for compare: " << type;
176174
}
177175
compareImport = func->name;
178176
found = true;
179177
} else if (func->base == "length") {
180-
if (sig != Signature({externref}, i32)) {
181-
Fatal() << "StringLifting: bad signature for length: " << sig;
178+
if (type != Signature({externref}, i32)) {
179+
Fatal() << "StringLifting: bad type for length: " << type;
182180
}
183181
lengthImport = func->name;
184182
found = true;
185183
} else if (func->base == "charCodeAt") {
186-
if (sig != Signature({externref, i32}, i32)) {
187-
Fatal() << "StringLifting: bad signature for charCodeAt: " << sig;
184+
if (type != Signature({externref, i32}, i32)) {
185+
Fatal() << "StringLifting: bad type for charCodeAt: " << type;
188186
}
189187
charCodeAtImport = func->name;
190188
found = true;
191189
} else if (func->base == "substring") {
192-
if (sig != Signature({externref, i32, i32}, refExtern)) {
193-
Fatal() << "StringLifting: bad signature for substring: " << sig;
190+
if (type != Signature({externref, i32, i32}, refExtern)) {
191+
Fatal() << "StringLifting: bad type for substring: " << type;
194192
}
195193
substringImport = func->name;
196194
found = true;

test/lit/passes/string-lifting-validation.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@
1818
)
1919

2020
;; RUN: not wasm-opt %s --string-lifting -all 2>&1 | filecheck %s
21-
;; CHECK: Fatal: StringLifting: bad signature for fromCharCodeArray: (func (param (ref null $array.0) i32 i64) (result (ref extern)))
21+
;; CHECK: Fatal: StringLifting: bad type for fromCharCodeArray: (type $func.0 (func (param (ref null $array.0) i32 i64) (result (ref extern))))
2222

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
;; The imported js string method here has the correct signature, but the wrong
2+
;; type. We should error.
3+
4+
(module
5+
(type $array16 (array (mut i16)))
6+
7+
;; The type should be final!
8+
(type $bad (sub (func (param (ref null $array16) i32 i32) (result (ref extern)))))
9+
10+
(import "wasm:js-string" "fromCharCodeArray" (func $fromCharCodeArray (type $bad)))
11+
12+
(func $string.new.gc (param $ref (ref $array16))
13+
(drop
14+
(call $fromCharCodeArray
15+
(local.get $ref)
16+
(i32.const 7)
17+
(i32.const 8)
18+
)
19+
)
20+
)
21+
)
22+
23+
;; RUN: not wasm-opt %s --string-lifting -all 2>&1 | filecheck %s
24+
;; CHECK: Fatal: StringLifting: bad type for fromCharCodeArray: (type $func.0 (sub (func (param (ref null $array.0) i32 i32) (result (ref extern)))))

0 commit comments

Comments
 (0)