diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2020-12-01 18:41:33 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-01 18:41:33 -0800 |
commit | 3b1d58aadd37ce8758447c9685d5c3a7bec9c418 (patch) | |
tree | 66a09c9f3d94384bbd983d70c410791d6609c7f6 /test/example/module-splitting.cpp | |
parent | a5403d47483836d5e2d53c3f3721bd376551624a (diff) | |
download | binaryen-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.cpp | 101 |
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 |