From 8971797b0bd3cdf89d6e8e3d8f67551a9792c064 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 27 Sep 2024 13:59:53 -0700 Subject: [PATCH 1/4] Expand tests for `array.new_data` Noticed that the existing tests didn't exercise out-of-bounds indexing of the data segment, so I added a test for that. At the same time, since I was already creating a dedicated `.wast` file for testing `array.new_data`, I also added a few general tests to round the file out. Some of these might technically duplicate things that already happen to be tested in `array.wast`, but I think that's probably fine, and that it is good to have dedicated tests in this new file. I can remove them if we'd rather not have these potential-duplicate tests. --- test/core/gc/array_new_data.wast | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 test/core/gc/array_new_data.wast diff --git a/test/core/gc/array_new_data.wast b/test/core/gc/array_new_data.wast new file mode 100644 index 000000000..397a86e35 --- /dev/null +++ b/test/core/gc/array_new_data.wast @@ -0,0 +1,50 @@ +(module + (type $arr (array (mut i8))) + + (data $d "abcd") + + (func (export "array-new-data") (param i32 i32) (result (ref $arr)) + (array.new_data $arr $d (local.get 0) (local.get 1)) + ) +) + +;; In-bounds data segment accesses. +(assert_return (invoke "array-new-data" (i32.const 0) (i32.const 0)) (ref.array)) +(assert_return (invoke "array-new-data" (i32.const 0) (i32.const 4)) (ref.array)) +(assert_return (invoke "array-new-data" (i32.const 1) (i32.const 2)) (ref.array)) +(assert_return (invoke "array-new-data" (i32.const 4) (i32.const 0)) (ref.array)) + +;; Out-of-bounds data segment accesses. +(assert_trap (invoke "array-new-data" (i32.const 0) (i32.const 5)) "out of bounds memory access") +(assert_trap (invoke "array-new-data" (i32.const 5) (i32.const 0)) "out of bounds memory access") + +(module + (type $arr (array (mut i8))) + + (data $d "\aa\bb\cc\dd") + + (func (export "array-new-data-contents") (result i32 i32) + (local (ref null $arr)) + (local.set 0 (array.new_data $arr $d (i32.const 1) (i32.const 2))) + (array.get_u $arr (local.get 0) (i32.const 0)) + (array.get_u $arr (local.get 0) (i32.const 1)) + ) +) + +;; Array is initialized with the correct contents. +(assert_return (invoke "array-new-data-contents") (i32.const 0xbb) (i32.const 0xcc)) + +(module + (type $arr (array (mut i32))) + + (data $d "\aa\bb\cc\dd") + + (func (export "array-new-data-little-endian") (result i32) + (array.get $arr + (array.new_data $arr $d (i32.const 0) (i32.const 1)) + (i32.const 0)) + ) +) + +;; Data segments are interpreted as little-endian. +(assert_return (invoke "array-new-data-little-endian") (i32.const 0xddccbbaa)) From f713000271658a7a52d34da17032f0a27b698969 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Sat, 28 Sep 2024 02:01:29 -0700 Subject: [PATCH 2/4] Remove nullability of local --- test/core/gc/array_new_data.wast | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/gc/array_new_data.wast b/test/core/gc/array_new_data.wast index 397a86e35..f55c28bf6 100644 --- a/test/core/gc/array_new_data.wast +++ b/test/core/gc/array_new_data.wast @@ -24,7 +24,7 @@ (data $d "\aa\bb\cc\dd") (func (export "array-new-data-contents") (result i32 i32) - (local (ref null $arr)) + (local (ref $arr)) (local.set 0 (array.new_data $arr $d (i32.const 1) (i32.const 2))) (array.get_u $arr (local.get 0) (i32.const 0)) (array.get_u $arr (local.get 0) (i32.const 1)) From 4c1061994fd2ca292d65d222ddce3d744383de04 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Sat, 28 Sep 2024 02:06:07 -0700 Subject: [PATCH 3/4] Add a couple more out-of-bounds data segment cases --- test/core/gc/array_new_data.wast | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/core/gc/array_new_data.wast b/test/core/gc/array_new_data.wast index f55c28bf6..da4865cf1 100644 --- a/test/core/gc/array_new_data.wast +++ b/test/core/gc/array_new_data.wast @@ -17,6 +17,9 @@ ;; Out-of-bounds data segment accesses. (assert_trap (invoke "array-new-data" (i32.const 0) (i32.const 5)) "out of bounds memory access") (assert_trap (invoke "array-new-data" (i32.const 5) (i32.const 0)) "out of bounds memory access") +(assert_trap (invoke "array-new-data" (i32.const 1) (i32.const 4)) "out of bounds memory access") +(assert_trap (invoke "array-new-data" (i32.const 4) (i32.const 1)) "out of bounds memory access") + (module (type $arr (array (mut i8))) From f846dd190d6b1965fcef66772516b11f9329b0c6 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Sat, 28 Sep 2024 02:06:39 -0700 Subject: [PATCH 4/4] Add an unualigned data segment access test for `array.new_data` --- test/core/gc/array_new_data.wast | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/core/gc/array_new_data.wast b/test/core/gc/array_new_data.wast index da4865cf1..2af894c16 100644 --- a/test/core/gc/array_new_data.wast +++ b/test/core/gc/array_new_data.wast @@ -51,3 +51,18 @@ ;; Data segments are interpreted as little-endian. (assert_return (invoke "array-new-data-little-endian") (i32.const 0xddccbbaa)) + +(module + (type $arr (array (mut i16))) + + (data $d "\00\11\22") + + (func (export "array-new-data-unaligned") (result i32) + (array.get_u $arr + (array.new_data $arr $d (i32.const 1) (i32.const 1)) + (i32.const 0)) + ) +) + +;; Data inside the segment doesn't need to be aligned to the element size. +(assert_return (invoke "array-new-data-unaligned") (i32.const 0x2211))