summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/module-splitting.cpp20
-rw-r--r--test/lit/wasm-split/no-active-segment.wast41
2 files changed, 54 insertions, 7 deletions
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index 966fb6779..50809a9a4 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -148,6 +148,8 @@ void TableSlotManager::addSlot(Name func, Slot slot) {
TableSlotManager::TableSlotManager(Module& module) : module(module) {
// TODO: Reject or handle passive element segments
+ // TODO: If reference types are enabled, just create a fresh table to make bad
+ // interactions with user code impossible.
auto funcref = Type(HeapType::func, Nullable);
auto it = std::find_if(
module.tables.begin(),
@@ -163,13 +165,17 @@ TableSlotManager::TableSlotManager(Module& module) : module(module) {
activeTableSegments.push_back(segment);
});
- // If there is exactly one table segment and that segment has a non-constant
- // offset, append new items to the end of that segment. In all other cases,
- // append new items at constant offsets after all existing items at constant
- // offsets.
- if (activeTableSegments.size() == 1 &&
- activeTableSegments[0]->type == funcref &&
- !activeTableSegments[0]->offset->is<Const>()) {
+ if (activeTableSegments.empty()) {
+ // There are no active segments, so we will lazily create one and start
+ // filling it at index 0.
+ activeBase = {activeTable->name, "", 0};
+ } else if (activeTableSegments.size() == 1 &&
+ activeTableSegments[0]->type == funcref &&
+ !activeTableSegments[0]->offset->is<Const>()) {
+ // If there is exactly one table segment and that segment has a non-constant
+ // offset, append new items to the end of that segment. In all other cases,
+ // append new items at constant offsets after all existing items at constant
+ // offsets.
assert(activeTableSegments[0]->offset->is<GlobalGet>() &&
"Unexpected initializer instruction");
activeSegment = activeTableSegments[0];
diff --git a/test/lit/wasm-split/no-active-segment.wast b/test/lit/wasm-split/no-active-segment.wast
new file mode 100644
index 000000000..ad83b0480
--- /dev/null
+++ b/test/lit/wasm-split/no-active-segment.wast
@@ -0,0 +1,41 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+
+;; Test that splitting succeeds even if there are no active segments for the function table.
+
+;; RUN: wasm-split %s --split-funcs=foo -g -o1 %t.1.wasm -o2 %t.2.wasm
+;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY
+;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY
+
+(module
+ (table 0 funcref)
+ (export "foo" (func $foo))
+ ;; SECONDARY: (type $0 (func))
+
+ ;; SECONDARY: (import "primary" "table" (table $timport$0 1 funcref))
+
+ ;; SECONDARY: (elem $0 (i32.const 0) $foo)
+
+ ;; SECONDARY: (func $foo
+ ;; SECONDARY-NEXT: (nop)
+ ;; SECONDARY-NEXT: )
+ (func $foo
+ (nop)
+ )
+)
+;; PRIMARY: (type $0 (func))
+
+;; PRIMARY: (import "placeholder" "0" (func $placeholder_0))
+
+;; PRIMARY: (table $0 1 funcref)
+
+;; PRIMARY: (elem $0 (i32.const 0) $placeholder_0)
+
+;; PRIMARY: (export "foo" (func $0))
+
+;; PRIMARY: (export "table" (table $0))
+
+;; PRIMARY: (func $0
+;; PRIMARY-NEXT: (call_indirect (type $0)
+;; PRIMARY-NEXT: (i32.const 0)
+;; PRIMARY-NEXT: )
+;; PRIMARY-NEXT: )