diff options
-rw-r--r-- | src/ir/module-splitting.cpp | 20 | ||||
-rw-r--r-- | test/lit/wasm-split/no-active-segment.wast | 41 |
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: ) |