Skip to content

Commit 0578862

Browse files
authored
Fix MemoryPacking handling of array.init_data (WebAssembly#5644)
Do not optimize out or split segments that are referred to array.init_data instructions. Fixes a bug where segments could get optimized out, producing invalid modules. Doing the work to actually split segments used by array.init_data is left for the future. Also fix a latent UBSan failure revealed by the new test case.
1 parent 642d663 commit 0578862

2 files changed

Lines changed: 35 additions & 5 deletions

File tree

src/passes/MemoryPacking.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ bool MemoryPacking::canSplit(const std::unique_ptr<DataSegment>& segment,
278278
return false;
279279
}
280280
}
281-
} else if (referrer->is<ArrayNewSeg>()) {
282-
// TODO: Split segments referenced by array.new_data instructions.
281+
} else if (referrer->is<ArrayNewSeg>() || referrer->is<ArrayInit>()) {
282+
// TODO: Split segments referenced by GC instructions.
283283
return false;
284284
}
285285
}
@@ -479,8 +479,10 @@ void MemoryPacking::getSegmentReferrers(Module* module,
479479
referrers[curr->segment].push_back(curr);
480480
}
481481
}
482-
void doWalkFunction(Function* func) {
483-
super::doWalkFunction(func);
482+
void visitArrayInit(ArrayInit* curr) {
483+
if (curr->op == InitData) {
484+
referrers[curr->segment].push_back(curr);
485+
}
484486
}
485487
} collector(referrers);
486488
collector.walkFunctionInModule(func, module);
@@ -586,7 +588,7 @@ void MemoryPacking::createSplitSegments(
586588
segment->memory,
587589
segment->isPassive,
588590
offset,
589-
&segment->data[range.start],
591+
segment->data.data() + range.start,
590592
range.end - range.start);
591593
curr->hasExplicitName = hasExplicitName;
592594
packed.push_back(std::move(curr));

test/lit/passes/memory-packing_all-features.wast

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,3 +2389,31 @@
23892389
)
23902390
)
23912391
)
2392+
(module
2393+
;; CHECK: (type $array (array (mut i32)))
2394+
(type $array (array (mut i32)))
2395+
;; CHECK: (type $ref|$array|_i32_i32_i32_=>_none (func (param (ref $array) i32 i32 i32)))
2396+
2397+
;; CHECK: (memory $0 (shared 16 17))
2398+
(memory $0 (shared 16 17))
2399+
;; CHECK: (data $0 "")
2400+
(data $0 "")
2401+
;; CHECK: (func $0 (type $ref|$array|_i32_i32_i32_=>_none) (param $0 (ref $array)) (param $1 i32) (param $2 i32) (param $3 i32)
2402+
;; CHECK-NEXT: (array.init_data $array $0
2403+
;; CHECK-NEXT: (local.get $0)
2404+
;; CHECK-NEXT: (i32.const 0)
2405+
;; CHECK-NEXT: (i32.const 0)
2406+
;; CHECK-NEXT: (i32.const 0)
2407+
;; CHECK-NEXT: )
2408+
;; CHECK-NEXT: )
2409+
(func $0 (param $0 (ref $array)) (param $1 i32) (param $2 i32) (param $3 i32)
2410+
;; test that we do not improperly optimize out segments referred to by
2411+
;; array.init_data instructions.
2412+
(array.init_data $array $0
2413+
(local.get $0)
2414+
(i32.const 0)
2415+
(i32.const 0)
2416+
(i32.const 0)
2417+
)
2418+
)
2419+
)

0 commit comments

Comments
 (0)