Skip to content

Commit e5c089d

Browse files
committed
[wasm-split] Fix infinite loop bug in table patching
We should skip all active segments in the active table when creating trampolines for indirect references. Currently we only do it for the last active segment, in case there are multiple of them.
1 parent 226787d commit e5c089d

2 files changed

Lines changed: 38 additions & 4 deletions

File tree

src/ir/module-splitting.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -979,13 +979,13 @@ void ModuleSplitter::indirectReferencesToSecondaryFunctions() {
979979
gatherer.walkModule(secondaryPtr.get());
980980
}
981981

982-
// Ignore references to secondary functions that occur in the active segment
982+
// Ignore references to secondary functions that occur in the active segments
983983
// that will contain the imported placeholders. Indirect calls to table slots
984-
// initialized by that segment will already go to the right place once the
984+
// initialized by those segments will already go to the right place once the
985985
// secondary module has been loaded and the table has been patched.
986986
std::unordered_set<RefFunc*> ignore;
987-
if (tableManager.activeSegment) {
988-
for (auto* expr : tableManager.activeSegment->data) {
987+
for (auto* segment : tableManager.activeTableSegments) {
988+
for (auto* expr : segment->data) {
989989
if (auto* ref = expr->dynCast<RefFunc>()) {
990990
ignore.insert(ref);
991991
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
2+
;; RUN: wasm-split %s --disable-reference-types --split-funcs=split -g -o1 %t.1.wasm -o2 %t.2.wasm
3+
;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY
4+
5+
;; Regression test for a bug that we incorrectly created a trampoline for
6+
;; (elem $e0 (i32.const 0) $split) segment, even though it was one of active
7+
;; segments.
8+
9+
(module
10+
;; PRIMARY: (type $0 (func))
11+
(type $0 (func))
12+
;; PRIMARY: (table $active_table 2 2 funcref)
13+
(table $active_table 2 2 funcref)
14+
;; PRIMARY: (elem $e0 (i32.const 0) $placeholder_0)
15+
16+
;; PRIMARY: (elem $e1 (i32.const 1) $keep)
17+
18+
;; PRIMARY: (export "active_table" (table $active_table))
19+
(export "active_table" (table $active_table))
20+
21+
(elem $e0 (i32.const 0) $split)
22+
(elem $e1 (i32.const 1) $keep)
23+
24+
;; PRIMARY: (func $keep
25+
;; PRIMARY-NEXT: (nop)
26+
;; PRIMARY-NEXT: )
27+
(func $keep (type $0)
28+
(nop)
29+
)
30+
31+
(func $split (type $0)
32+
(nop)
33+
)
34+
)

0 commit comments

Comments
 (0)