diff options
author | Thomas Lively <tlively@google.com> | 2022-11-07 12:45:01 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-07 12:45:01 -0800 |
commit | b48e4de5ea13434ded315b2bc99a713db0361f63 (patch) | |
tree | a1c24b6f79c624f9affb538e1daf18e67d386743 /test | |
parent | 52079ae8ea3abec509c3184720d1824b9093cb2f (diff) | |
download | binaryen-b48e4de5ea13434ded315b2bc99a713db0361f63.tar.gz binaryen-b48e4de5ea13434ded315b2bc99a713db0361f63.tar.bz2 binaryen-b48e4de5ea13434ded315b2bc99a713db0361f63.zip |
Implement `array.new_data` and `array.new_elem` (#5214)
In order to test them, fix the binary and text parsers to accept passive data
segments even if a module has no memory. In addition to parsing and emitting the
new instructions, also implement their validation and interpretation. Test the
interpretation directly with wasm-shell tests adapted from the upstream spec
tests. Running the upstream spec tests directly would require fixing too many
bugs in the legacy text parser, so it will have to wait for the new text parser
to be ready.
Diffstat (limited to 'test')
-rw-r--r-- | test/binaryen.js/kitchen-sink.js.txt | 38 | ||||
-rw-r--r-- | test/lit/arrays.wast | 72 | ||||
-rw-r--r-- | test/spec/array-new-data.wast | 79 | ||||
-rw-r--r-- | test/spec/array-new-elem.wast | 48 |
4 files changed, 212 insertions, 25 deletions
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 89c49f2d5..9200bac2a 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -97,25 +97,25 @@ StructNewId: 60 StructGetId: 61 StructSetId: 62 ArrayNewId: 63 -ArrayInitId: 64 -ArrayGetId: 65 -ArraySetId: 66 -ArrayLenId: 67 -ArrayCopy: 68 -RefAs: 69 -StringNew: 70 -StringConst: 71 -StringMeasure: 72 -StringEncode: 73 -StringConcat: 74 -StringEq: 75 -StringAs: 76 -StringWTF8Advance: 77 -StringWTF16Get: 78 -StringIterNext: 79 -StringIterMove: 80 -StringSliceWTF: 81 -StringSliceIter: 82 +ArrayInitId: 65 +ArrayGetId: 66 +ArraySetId: 67 +ArrayLenId: 68 +ArrayCopy: 69 +RefAs: 70 +StringNew: 71 +StringConst: 72 +StringMeasure: 73 +StringEncode: 74 +StringConcat: 75 +StringEq: 76 +StringAs: 77 +StringWTF8Advance: 78 +StringWTF16Get: 79 +StringIterNext: 80 +StringIterMove: 81 +StringSliceWTF: 82 +StringSliceIter: 83 getExpressionInfo={"id":15,"type":4,"op":6} (f32.neg (f32.const -33.61199951171875) diff --git a/test/lit/arrays.wast b/test/lit/arrays.wast index 31aead1cd..4a262ef13 100644 --- a/test/lit/arrays.wast +++ b/test/lit/arrays.wast @@ -10,24 +10,46 @@ ;; RUN: wasm-opt %s -all -S -o - | wasm-opt -all -S -o - | filecheck %s (module - (type $byte-array (array (mut i8))) ;; CHECK: (type $arrayref_=>_i32 (func (param arrayref) (result i32))) ;; CHECK: (type $ref|array|_=>_i32 (func (param (ref array)) (result i32))) ;; CHECK: (type $nullref_=>_i32 (func (param nullref) (result i32))) - ;; CHECK: (func $len (param $a (ref array)) (result i32) - ;; CHECK-NEXT: (array.len - ;; CHECK-NEXT: (local.get $a) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) + ;; CHECK: (type $none_=>_ref|$byte-array| (func (result (ref $byte-array)))) + + ;; CHECK: (type $none_=>_ref|$func-array| (func (result (ref $func-array)))) + + ;; CHECK: (type $byte-array (array (mut i8))) ;; ROUNDTRIP: (type $arrayref_=>_i32 (func (param arrayref) (result i32))) ;; ROUNDTRIP: (type $ref|array|_=>_i32 (func (param (ref array)) (result i32))) ;; ROUNDTRIP: (type $nullref_=>_i32 (func (param nullref) (result i32))) + ;; ROUNDTRIP: (type $none_=>_ref|$byte-array| (func (result (ref $byte-array)))) + + ;; ROUNDTRIP: (type $none_=>_ref|$func-array| (func (result (ref $func-array)))) + + ;; ROUNDTRIP: (type $byte-array (array (mut i8))) + (type $byte-array (array (mut i8))) + ;; CHECK: (type $func-array (array (mut funcref))) + ;; ROUNDTRIP: (type $func-array (array (mut funcref))) + (type $func-array (array (mut funcref))) + + ;; CHECK: (data "hello") + ;; ROUNDTRIP: (data "hello") + (data "hello") + ;; CHECK: (elem func $len $impossible-len $unreachable-len) + ;; ROUNDTRIP: (elem func $len $impossible-len $unreachable-len) + (elem func $len $impossible-len $unreachable-len) + + + ;; CHECK: (func $len (param $a (ref array)) (result i32) + ;; CHECK-NEXT: (array.len + ;; CHECK-NEXT: (local.get $a) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; ROUNDTRIP: (func $len (param $a (ref array)) (result i32) ;; ROUNDTRIP-NEXT: (array.len ;; ROUNDTRIP-NEXT: (local.get $a) @@ -85,4 +107,42 @@ (local.get $a) ) ) + + ;; CHECK: (func $new-data (result (ref $byte-array)) + ;; CHECK-NEXT: (array.new_data $byte-array 0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $new-data (result (ref $byte-array)) + ;; ROUNDTRIP-NEXT: (array.new_data $byte-array 0 + ;; ROUNDTRIP-NEXT: (i32.const 0) + ;; ROUNDTRIP-NEXT: (i32.const 5) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: ) + (func $new-data (result (ref $byte-array)) + (array.new_data $byte-array 0 + (i32.const 0) + (i32.const 5) + ) + ) + + ;; CHECK: (func $new-elem (result (ref $func-array)) + ;; CHECK-NEXT: (array.new_elem $func-array 0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; ROUNDTRIP: (func $new-elem (result (ref $func-array)) + ;; ROUNDTRIP-NEXT: (array.new_elem $func-array 0 + ;; ROUNDTRIP-NEXT: (i32.const 0) + ;; ROUNDTRIP-NEXT: (i32.const 3) + ;; ROUNDTRIP-NEXT: ) + ;; ROUNDTRIP-NEXT: ) + (func $new-elem (result (ref $func-array)) + (array.new_elem $func-array 0 + (i32.const 0) + (i32.const 3) + ) + ) ) diff --git a/test/spec/array-new-data.wast b/test/spec/array-new-data.wast new file mode 100644 index 000000000..8ef62cb87 --- /dev/null +++ b/test/spec/array-new-data.wast @@ -0,0 +1,79 @@ +(module + (type $vec (array i8)) + (type $mvec (array (mut i8))) + + (data "\00\01\02\03\04") + + (func $new (export "new") (result (ref $vec)) + (array.new_data $vec 0 (i32.const 1) (i32.const 3)) + ) + + (func $get (param $i i32) (param $v (ref $vec)) (result i32) + (array.get_u $vec (local.get $v) (local.get $i)) + ) + (func (export "get") (param $i i32) (result i32) + (call $get (local.get $i) (call $new)) + ) + + (func $set_get (param $i i32) (param $v (ref $mvec)) (param $y i32) (result i32) + (array.set $mvec (local.get $v) (local.get $i) (local.get $y)) + (array.get_u $mvec (local.get $v) (local.get $i)) + ) + (func (export "set_get") (param $i i32) (param $y i32) (result i32) + (call $set_get (local.get $i) + (array.new_data $mvec 0 (i32.const 1) (i32.const 3)) + (local.get $y) + ) + ) + + (func $len (param $v (ref array)) (result i32) + (array.len (local.get $v)) + ) + (func (export "len") (result i32) + (call $len (call $new)) + ) +) + +(assert_return (invoke "get" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "set_get" (i32.const 1) (i32.const 7)) (i32.const 7)) +(assert_return (invoke "len") (i32.const 3)) + +(module + (type $vec (array i32)) + (type $mvec (array (mut i8))) + + (data "\00\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00") + + (func $new (export "new") (result (ref $vec)) + (array.new_data $vec 0 (i32.const 1) (i32.const 3)) + ) + + (func $get (param $i i32) (param $v (ref $vec)) (result i32) + (array.get $vec (local.get $v) (local.get $i)) + ) + (func (export "get") (param $i i32) (result i32) + (call $get (local.get $i) (call $new)) + ) + + (func $set_get (param $i i32) (param $v (ref $mvec)) (param $y i32) (result i32) + (array.set $mvec (local.get $v) (local.get $i) (local.get $y)) + (array.get $mvec (local.get $v) (local.get $i)) + ) + (func (export "set_get") (param $i i32) (param $y i32) (result i32) + (call $set_get (local.get $i) + (array.new_data $mvec 0 (i32.const 1) (i32.const 3)) + (local.get $y) + ) + ) + + (func $len (param $v (ref array)) (result i32) + (array.len (local.get $v)) + ) + (func (export "len") (result i32) + (call $len (call $new)) + ) +) + +(assert_return (invoke "get" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "set_get" (i32.const 1) (i32.const 7)) (i32.const 7)) +(assert_return (invoke "len") (i32.const 3)) diff --git a/test/spec/array-new-elem.wast b/test/spec/array-new-elem.wast new file mode 100644 index 000000000..a61122bd6 --- /dev/null +++ b/test/spec/array-new-elem.wast @@ -0,0 +1,48 @@ +(module + (type $vec (array funcref)) + (type $mvec (array (mut funcref))) + (type $f (func (result i32))) + + (elem func $ret0 $ret1 $ret2 $ret3 $ret4) + + (func $ret0 (type $f) (i32.const 0)) + (func $ret1 (type $f) (i32.const 1)) + (func $ret2 (type $f) (i32.const 2)) + (func $ret3 (type $f) (i32.const 3)) + (func $ret4 (type $f) (i32.const 4)) + + (func $new (export "new") (result (ref $vec)) + (array.new_elem $vec 0 (i32.const 1) (i32.const 3)) + ) + + (func $get (param $i i32) (param $v (ref $vec)) (result i32) + (call_ref $f (ref.cast_static $f (array.get $vec (local.get $v) (local.get $i)))) + ) + (func (export "get") (param $i i32) (result i32) + (call $get (local.get $i) (call $new)) + ) + + (func $set_get (param $i i32) (param $v (ref $mvec)) (param $y i32) (result i32) + (array.set $mvec (local.get $v) (local.get $i) (array.get $mvec (local.get $v) (local.get $y))) + (call_ref $f (ref.cast_static $f (array.get $mvec (local.get $v) (local.get $i)))) + ) + (func (export "set_get") (param $i i32) (param $y i32) (result i32) + (call $set_get + (local.get $i) + (array.new_elem $mvec 0 (i32.const 1) (i32.const 3)) + (local.get $y) + ) + ) + + (func $len (param $v (ref array)) (result i32) + (array.len (local.get $v)) + ) + (func (export "len") (result i32) + (call $len (call $new)) + ) +) + +(assert_return (invoke "get" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "get" (i32.const 1)) (i32.const 2)) +(assert_return (invoke "set_get" (i32.const 0) (i32.const 2)) (i32.const 3)) +(assert_return (invoke "len") (i32.const 3)) |