summaryrefslogtreecommitdiff
path: root/test/example/module-splitting.cpp
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-12-01 18:41:33 -0800
committerGitHub <noreply@github.com>2020-12-01 18:41:33 -0800
commit3b1d58aadd37ce8758447c9685d5c3a7bec9c418 (patch)
tree66a09c9f3d94384bbd983d70c410791d6609c7f6 /test/example/module-splitting.cpp
parenta5403d47483836d5e2d53c3f3721bd376551624a (diff)
downloadbinaryen-3b1d58aadd37ce8758447c9685d5c3a7bec9c418.tar.gz
binaryen-3b1d58aadd37ce8758447c9685d5c3a7bec9c418.tar.bz2
binaryen-3b1d58aadd37ce8758447c9685d5c3a7bec9c418.zip
[module-splitting] Allow splitting with non-const table offsets (#3408)
Extend the splitting logic to handle splitting modules with a single table segment with a non-const offset. In this situation the placeholder function names are interpreted as offsets from the table base global rather than absolute indices into the table. Since addition is not allowed in segment offset expressions, the secondary module's segment must start at the same place as the first table's segment. That means that some primary functions must be duplicated in the secondary segment to fill any gaps. They are exported and imported as necessary.
Diffstat (limited to 'test/example/module-splitting.cpp')
-rw-r--r--test/example/module-splitting.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/test/example/module-splitting.cpp b/test/example/module-splitting.cpp
index 50fb0f4c5..bba0bf0a7 100644
--- a/test/example/module-splitting.cpp
+++ b/test/example/module-splitting.cpp
@@ -127,6 +127,17 @@ int main() {
)
))");
+ // Non-deferred function in table at non-const offset
+ do_test({"foo"}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (table $table 1 funcref)
+ (elem (global.get $base) $foo)
+ (func $foo (param i32) (result i32)
+ (local.get 0)
+ )
+ ))");
+
// Non-deferred imported function
do_test({"foo"}, R"(
(module
@@ -142,6 +153,16 @@ int main() {
(export "foo" (func $foo))
))");
+ // Non-deferred exported imported function in table at a non-const offset
+ do_test({"foo"}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (import "env" "foo" (func $foo (param i32) (result i32)))
+ (table $table 1000 funcref)
+ (elem (global.get $base) $foo)
+ (export "foo" (func $foo))
+ ))");
+
// Deferred function
do_test({}, R"(
(module
@@ -180,6 +201,31 @@ int main() {
)
))");
+ // Deferred exported function in table at a non-const offset
+ do_test({}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (table $table 1000 funcref)
+ (elem (global.get $base) $foo)
+ (export "foo" (func $foo))
+ (func $foo (param i32) (result i32)
+ (local.get 0)
+ )
+ ))");
+
+ // Deferred exported function in table at an offset from a non-const base
+ do_test({"null"}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (table $table 1000 funcref)
+ (elem (global.get $base) $null $foo)
+ (export "foo" (func $foo))
+ (func $null)
+ (func $foo (param i32) (result i32)
+ (local.get 0)
+ )
+ ))");
+
// Non-deferred function calling non-deferred function
do_test({"foo", "bar"}, R"(
(module
@@ -255,6 +301,26 @@ int main() {
)
))");
+ // Mixed table 1 with non-const offset
+ do_test({"bar", "quux"}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (table $table 4 funcref)
+ (elem (global.get $base) $foo $bar $baz $quux)
+ (func $foo
+ (nop)
+ )
+ (func $bar
+ (nop)
+ )
+ (func $baz
+ (nop)
+ )
+ (func $quux
+ (nop)
+ )
+ ))");
+
// Mixed table 2
do_test({"baz"}, R"(
(module
@@ -274,6 +340,41 @@ int main() {
)
))");
+ // Mixed table 2 with non-const offset
+ do_test({"baz"}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (table $table 4 funcref)
+ (elem (global.get $base) $foo $bar $baz $quux)
+ (func $foo
+ (nop)
+ )
+ (func $bar
+ (nop)
+ )
+ (func $baz
+ (nop)
+ )
+ (func $quux
+ (nop)
+ )
+ ))");
+
+ // `foo` is exported both because it is called by `bar` and because it is in a
+ // table gap
+ do_test({"foo"}, R"(
+ (module
+ (import "env" "base" (global $base i32))
+ (table $table 2 funcref)
+ (elem (global.get $base) $foo $bar)
+ (func $foo
+ (nop)
+ )
+ (func $bar
+ (call $foo)
+ )
+ ))");
+
// Mutual recursion with table growth
do_test({"foo"}, R"(
(module