Skip to content

Commit dfab223

Browse files
authored
[Strings] Fix StringLowering of reference-taken functions (#7613)
We manually update the types of functions that have size 1 rec groups, because we need to update imports and exports, even though that changes the ABI - something TypeMapper does not do, but StringLowering wants. See the existing comment for details. That code updated those types, but did just themselves - it did not go through the code to find RefFuncs of them, which left them with the old type, causing errors. To fix this, tell TypeUpdater to map those types (it doesn't know it needs to automatically, since we manually handled them).
1 parent 5d894fc commit dfab223

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

src/passes/StringLowering.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ struct StringLowering : public StringGathering {
288288
Type nnExt = Type(HeapType::ext, NonNullable);
289289

290290
void updateTypes(Module* module) {
291+
TypeMapper::TypeUpdates updates;
292+
291293
// TypeMapper will not handle public types, but we do want to modify them as
292294
// well: we are modifying the public ABI here. We can't simply tell
293295
// TypeMapper to consider them private, as then they'd end up in the new big
@@ -324,11 +326,14 @@ struct StringLowering : public StringGathering {
324326
for (auto result : func->type.getSignature().results) {
325327
results.push_back(fix(result));
326328
}
329+
330+
// In addition to doing the update, mark it in the map of updates for
331+
// TypeMapper, so RefFuncs with this type get updated.
332+
auto old = func->type;
327333
func->type = Signature(params, results);
334+
updates[old] = func->type;
328335
}
329336

330-
TypeMapper::TypeUpdates updates;
331-
332337
// Strings turn into externref.
333338
updates[HeapType::string] = HeapType::ext;
334339

test/lit/passes/string-lowering_types.wast

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,64 @@
7171
(local (ref $private))
7272
)
7373
)
74+
75+
;; A function returning a string is taken by reference. We should update the
76+
;; ref.funcs for it, both in the table and in the code, and not error.
77+
(module
78+
;; CHECK: (type $0 (array (mut i16)))
79+
80+
;; CHECK: (type $1 (func (param externref externref) (result i32)))
81+
82+
;; CHECK: (type $2 (func (result (ref extern))))
83+
84+
;; CHECK: (type $3 (func (param (ref null $0) i32 i32) (result (ref extern))))
85+
86+
;; CHECK: (type $4 (func (param i32) (result (ref extern))))
87+
88+
;; CHECK: (type $5 (func (param externref externref) (result (ref extern))))
89+
90+
;; CHECK: (type $6 (func (param externref (ref null $0) i32) (result i32)))
91+
92+
;; CHECK: (type $7 (func (param externref) (result i32)))
93+
94+
;; CHECK: (type $8 (func (param externref i32) (result i32)))
95+
96+
;; CHECK: (type $9 (func (param externref i32 i32) (result (ref extern))))
97+
98+
;; CHECK: (import "wasm:js-string" "fromCharCodeArray" (func $fromCharCodeArray (type $3) (param (ref null $0) i32 i32) (result (ref extern))))
99+
100+
;; CHECK: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint (type $4) (param i32) (result (ref extern))))
101+
102+
;; CHECK: (import "wasm:js-string" "concat" (func $concat (type $5) (param externref externref) (result (ref extern))))
103+
104+
;; CHECK: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $6) (param externref (ref null $0) i32) (result i32)))
105+
106+
;; CHECK: (import "wasm:js-string" "equals" (func $equals (type $1) (param externref externref) (result i32)))
107+
108+
;; CHECK: (import "wasm:js-string" "compare" (func $compare (type $1) (param externref externref) (result i32)))
109+
110+
;; CHECK: (import "wasm:js-string" "length" (func $length (type $7) (param externref) (result i32)))
111+
112+
;; CHECK: (import "wasm:js-string" "charCodeAt" (func $charCodeAt (type $8) (param externref i32) (result i32)))
113+
114+
;; CHECK: (import "wasm:js-string" "substring" (func $substring (type $9) (param externref i32 i32) (result (ref extern))))
115+
116+
;; CHECK: (table $table 31 31 funcref)
117+
(table $table 31 31 funcref)
118+
119+
;; CHECK: (elem $elem (i32.const 0) $func)
120+
(elem $elem (i32.const 0) $func)
121+
122+
;; CHECK: (func $func (type $2) (result (ref extern))
123+
;; CHECK-NEXT: (drop
124+
;; CHECK-NEXT: (ref.func $func)
125+
;; CHECK-NEXT: )
126+
;; CHECK-NEXT: (unreachable)
127+
;; CHECK-NEXT: )
128+
(func $func (result (ref string))
129+
(drop
130+
(ref.func $func)
131+
)
132+
(unreachable)
133+
)
134+
)

0 commit comments

Comments
 (0)