Skip to content

Commit 6eb8356

Browse files
Shared string builtins
1 parent 3ce53e8 commit 6eb8356

12 files changed

+893
-287
lines changed

src/passes/StringLifting.cpp

Lines changed: 148 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ struct StringLifting : public Pass {
5050
Name charCodeAtImport;
5151
Name substringImport;
5252

53+
// Shared imported string functions.
54+
Name fromCharCodeArraySharedImport;
55+
Name intoCharCodeArraySharedImport;
56+
Name fromCodePointSharedImport;
57+
Name concatSharedImport;
58+
Name equalsSharedImport;
59+
Name testSharedImport;
60+
Name compareSharedImport;
61+
Name lengthSharedImport;
62+
Name charCodeAtSharedImport;
63+
Name substringSharedImport;
64+
5365
void run(Module* module) override {
5466
// Whether we found any work to do.
5567
bool found = false;
@@ -121,79 +133,142 @@ struct StringLifting : public Pass {
121133
module->customSections.erase(stringSectionIter);
122134
}
123135

124-
auto array16 = Type(Array(Field(Field::i16, Mutable)), Nullable);
136+
auto array16 = Type(HeapTypes::getMutI16Array(), Nullable);
125137
auto refExtern = Type(HeapType::ext, NonNullable);
126138
auto externref = Type(HeapType::ext, Nullable);
127139
auto i32 = Type::i32;
128140

141+
auto sharedArray16 = Type(HeapTypes::getSharedMutI16Array(), Nullable);
142+
auto refSharedExtern =
143+
Type(HeapType(HeapType::ext).getBasic(Shared), NonNullable);
144+
auto sharedExternref =
145+
Type(HeapType(HeapType::ext).getBasic(Shared), Nullable);
146+
129147
// Find imported string functions.
130148
for (auto& func : module->functions) {
131149
if (!func->imported() || func->module != WasmStringsModule) {
132150
continue;
133151
}
134-
// TODO: Check exactness here too.
135152
auto type = func->type;
136153
if (func->base == "fromCharCodeArray") {
137-
if (type.getHeapType() != Signature({array16, i32, i32}, refExtern)) {
154+
if (type.getHeapType() ==
155+
Signature(Type({array16, i32, i32}), refExtern)) {
156+
fromCharCodeArrayImport = func->name;
157+
found = true;
158+
} else if (type.getHeapType() ==
159+
Signature(Type({sharedArray16, i32, i32}),
160+
refSharedExtern)) {
161+
fromCharCodeArraySharedImport = func->name;
162+
found = true;
163+
} else {
138164
Fatal() << "StringLifting: bad type for fromCharCodeArray: " << type;
139165
}
140-
fromCharCodeArrayImport = func->name;
141-
found = true;
142166
} else if (func->base == "fromCodePoint") {
143-
if (type.getHeapType() != Signature(i32, refExtern)) {
167+
if (type.getHeapType() == Signature(i32, refExtern)) {
168+
fromCodePointImport = func->name;
169+
found = true;
170+
} else if (type.getHeapType() == Signature(i32, refSharedExtern)) {
171+
fromCodePointSharedImport = func->name;
172+
found = true;
173+
} else {
144174
Fatal() << "StringLifting: bad type for fromCodePoint: " << type;
145175
}
146-
fromCodePointImport = func->name;
147-
found = true;
148176
} else if (func->base == "concat") {
149-
if (type.getHeapType() !=
150-
Signature({externref, externref}, refExtern)) {
177+
if (type.getHeapType() ==
178+
Signature(Type({externref, externref}), refExtern)) {
179+
concatImport = func->name;
180+
found = true;
181+
} else if (type.getHeapType() ==
182+
Signature(Type({sharedExternref, sharedExternref}),
183+
refSharedExtern)) {
184+
concatSharedImport = func->name;
185+
found = true;
186+
} else {
151187
Fatal() << "StringLifting: bad type for concat: " << type;
152188
}
153-
concatImport = func->name;
154-
found = true;
155189
} else if (func->base == "intoCharCodeArray") {
156-
if (type.getHeapType() != Signature({externref, array16, i32}, i32)) {
190+
if (type.getHeapType() ==
191+
Signature(Type({externref, array16, i32}), i32)) {
192+
intoCharCodeArrayImport = func->name;
193+
found = true;
194+
} else if (type.getHeapType() ==
195+
Signature(Type({sharedExternref, sharedArray16, i32}),
196+
i32)) {
197+
intoCharCodeArraySharedImport = func->name;
198+
found = true;
199+
} else {
157200
Fatal() << "StringLifting: bad type for intoCharCodeArray: " << type;
158201
}
159-
intoCharCodeArrayImport = func->name;
160-
found = true;
161202
} else if (func->base == "equals") {
162-
if (type.getHeapType() != Signature({externref, externref}, i32)) {
203+
if (type.getHeapType() ==
204+
Signature(Type({externref, externref}), i32)) {
205+
equalsImport = func->name;
206+
found = true;
207+
} else if (type.getHeapType() ==
208+
Signature(Type({sharedExternref, sharedExternref}), i32)) {
209+
equalsSharedImport = func->name;
210+
found = true;
211+
} else {
163212
Fatal() << "StringLifting: bad type for equals: " << type;
164213
}
165-
equalsImport = func->name;
166-
found = true;
167214
} else if (func->base == "test") {
168-
if (type.getHeapType() != Signature({externref}, i32)) {
215+
if (type.getHeapType() == Signature(Type({externref}), i32)) {
216+
testImport = func->name;
217+
found = true;
218+
} else if (type.getHeapType() ==
219+
Signature(Type({sharedExternref}), i32)) {
220+
testSharedImport = func->name;
221+
found = true;
222+
} else {
169223
Fatal() << "StringLifting: bad type for test: " << type;
170224
}
171-
testImport = func->name;
172-
found = true;
173225
} else if (func->base == "compare") {
174-
if (type.getHeapType() != Signature({externref, externref}, i32)) {
226+
if (type.getHeapType() ==
227+
Signature(Type({externref, externref}), i32)) {
228+
compareImport = func->name;
229+
found = true;
230+
} else if (type.getHeapType() ==
231+
Signature(Type({sharedExternref, sharedExternref}), i32)) {
232+
compareSharedImport = func->name;
233+
found = true;
234+
} else {
175235
Fatal() << "StringLifting: bad type for compare: " << type;
176236
}
177-
compareImport = func->name;
178-
found = true;
179237
} else if (func->base == "length") {
180-
if (type.getHeapType() != Signature({externref}, i32)) {
238+
if (type.getHeapType() == Signature(Type({externref}), i32)) {
239+
lengthImport = func->name;
240+
found = true;
241+
} else if (type.getHeapType() ==
242+
Signature(Type({sharedExternref}), i32)) {
243+
lengthSharedImport = func->name;
244+
found = true;
245+
} else {
181246
Fatal() << "StringLifting: bad type for length: " << type;
182247
}
183-
lengthImport = func->name;
184-
found = true;
185248
} else if (func->base == "charCodeAt") {
186-
if (type.getHeapType() != Signature({externref, i32}, i32)) {
249+
if (type.getHeapType() == Signature(Type({externref, i32}), i32)) {
250+
charCodeAtImport = func->name;
251+
found = true;
252+
} else if (type.getHeapType() ==
253+
Signature(Type({sharedExternref, i32}), i32)) {
254+
charCodeAtSharedImport = func->name;
255+
found = true;
256+
} else {
187257
Fatal() << "StringLifting: bad type for charCodeAt: " << type;
188258
}
189-
charCodeAtImport = func->name;
190-
found = true;
191259
} else if (func->base == "substring") {
192-
if (type.getHeapType() != Signature({externref, i32, i32}, refExtern)) {
260+
if (type.getHeapType() ==
261+
Signature(Type({externref, i32, i32}), refExtern)) {
262+
substringImport = func->name;
263+
found = true;
264+
} else if (type.getHeapType() ==
265+
Signature(Type({sharedExternref, i32, i32}),
266+
refSharedExtern)) {
267+
substringSharedImport = func->name;
268+
found = true;
269+
} else {
193270
Fatal() << "StringLifting: bad type for substring: " << type;
194271
}
195-
substringImport = func->name;
196-
found = true;
197272
} else {
198273
std::cerr << "warning: unknown strings import: " << func->base << '\n';
199274
}
@@ -228,53 +303,51 @@ struct StringLifting : public Pass {
228303
}
229304

230305
void visitCall(Call* curr) {
306+
Builder builder(*getModule());
231307
// Replace calls of imported string methods with stringref operations.
232-
if (curr->target == parent.fromCharCodeArrayImport) {
233-
replaceCurrent(Builder(*getModule())
234-
.makeStringNew(StringNewWTF16Array,
235-
curr->operands[0],
236-
curr->operands[1],
237-
curr->operands[2]));
238-
} else if (curr->target == parent.fromCodePointImport) {
239-
replaceCurrent(
240-
Builder(*getModule())
241-
.makeStringNew(StringNewFromCodePoint, curr->operands[0]));
242-
} else if (curr->target == parent.concatImport) {
308+
if (curr->target == parent.fromCharCodeArrayImport ||
309+
curr->target == parent.fromCharCodeArraySharedImport) {
310+
replaceCurrent(builder.makeStringNew(StringNewWTF16Array,
311+
curr->operands[0],
312+
curr->operands[1],
313+
curr->operands[2]));
314+
} else if (curr->target == parent.fromCodePointImport ||
315+
curr->target == parent.fromCodePointSharedImport) {
243316
replaceCurrent(
244-
Builder(*getModule())
245-
.makeStringConcat(curr->operands[0], curr->operands[1]));
246-
} else if (curr->target == parent.intoCharCodeArrayImport) {
247-
replaceCurrent(Builder(*getModule())
248-
.makeStringEncode(StringEncodeWTF16Array,
249-
curr->operands[0],
250-
curr->operands[1],
251-
curr->operands[2]));
252-
} else if (curr->target == parent.equalsImport) {
253-
replaceCurrent(Builder(*getModule())
254-
.makeStringEq(StringEqEqual,
255-
curr->operands[0],
256-
curr->operands[1]));
257-
} else if (curr->target == parent.testImport) {
317+
builder.makeStringNew(StringNewFromCodePoint, curr->operands[0]));
318+
} else if (curr->target == parent.concatImport ||
319+
curr->target == parent.concatSharedImport) {
258320
replaceCurrent(
259-
Builder(*getModule()).makeStringTest(curr->operands[0]));
260-
} else if (curr->target == parent.compareImport) {
261-
replaceCurrent(Builder(*getModule())
262-
.makeStringEq(StringEqCompare,
263-
curr->operands[0],
264-
curr->operands[1]));
265-
} else if (curr->target == parent.lengthImport) {
321+
builder.makeStringConcat(curr->operands[0], curr->operands[1]));
322+
} else if (curr->target == parent.intoCharCodeArrayImport ||
323+
curr->target == parent.intoCharCodeArraySharedImport) {
324+
replaceCurrent(builder.makeStringEncode(StringEncodeWTF16Array,
325+
curr->operands[0],
326+
curr->operands[1],
327+
curr->operands[2]));
328+
} else if (curr->target == parent.equalsImport ||
329+
curr->target == parent.equalsSharedImport) {
330+
replaceCurrent(builder.makeStringEq(
331+
StringEqEqual, curr->operands[0], curr->operands[1]));
332+
} else if (curr->target == parent.testImport ||
333+
curr->target == parent.testSharedImport) {
334+
replaceCurrent(builder.makeStringTest(curr->operands[0]));
335+
} else if (curr->target == parent.compareImport ||
336+
curr->target == parent.compareSharedImport) {
337+
replaceCurrent(builder.makeStringEq(
338+
StringEqCompare, curr->operands[0], curr->operands[1]));
339+
} else if (curr->target == parent.lengthImport ||
340+
curr->target == parent.lengthSharedImport) {
266341
replaceCurrent(
267-
Builder(*getModule())
268-
.makeStringMeasure(StringMeasureWTF16, curr->operands[0]));
269-
} else if (curr->target == parent.charCodeAtImport) {
342+
builder.makeStringMeasure(StringMeasureWTF16, curr->operands[0]));
343+
} else if (curr->target == parent.charCodeAtImport ||
344+
curr->target == parent.charCodeAtSharedImport) {
270345
replaceCurrent(
271-
Builder(*getModule())
272-
.makeStringWTF16Get(curr->operands[0], curr->operands[1]));
273-
} else if (curr->target == parent.substringImport) {
274-
replaceCurrent(Builder(*getModule())
275-
.makeStringSliceWTF(curr->operands[0],
276-
curr->operands[1],
277-
curr->operands[2]));
346+
builder.makeStringWTF16Get(curr->operands[0], curr->operands[1]));
347+
} else if (curr->target == parent.substringImport ||
348+
curr->target == parent.substringSharedImport) {
349+
replaceCurrent(builder.makeStringSliceWTF(
350+
curr->operands[0], curr->operands[1], curr->operands[2]));
278351
}
279352
}
280353

0 commit comments

Comments
 (0)