summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-11 15:11:25 -0800
committerGitHub <noreply@github.com>2021-03-11 15:11:25 -0800
commit1f695bc88423abcf03c006e62f137ac0e76f93df (patch)
tree8f45e12fe97eb099e01329588a48a57b776a11f3 /test
parent484563771dbca78e5323cc3f5129890aea03aed5 (diff)
downloadbinaryen-1f695bc88423abcf03c006e62f137ac0e76f93df.tar.gz
binaryen-1f695bc88423abcf03c006e62f137ac0e76f93df.tar.bz2
binaryen-1f695bc88423abcf03c006e62f137ac0e76f93df.zip
[Wasm GC] Add more passing spec tests. (#3677)
Diffstat (limited to 'test')
-rw-r--r--test/spec/call_ref.wast135
-rw-r--r--test/spec/i31.wast30
-rw-r--r--test/spec/ref_as_non_null.wast28
-rw-r--r--test/spec/struct.wast98
4 files changed, 291 insertions, 0 deletions
diff --git a/test/spec/call_ref.wast b/test/spec/call_ref.wast
new file mode 100644
index 000000000..8a34706f2
--- /dev/null
+++ b/test/spec/call_ref.wast
@@ -0,0 +1,135 @@
+(module
+ (type $ii (func (param i32) (result i32)))
+
+ (func $apply (param $f (ref $ii)) (param $x i32) (result i32)
+ (call_ref (local.get $x) (local.get $f))
+ )
+
+ (func $f (type $ii) (i32.mul (local.get 0) (local.get 0)))
+ (func $g (type $ii) (i32.sub (i32.const 0) (local.get 0)))
+
+ (elem declare func $f $g)
+
+ (func (export "run") (param $x i32) (result i32)
+ (local $rf (ref null $ii))
+ (local $rg (ref null $ii))
+ (local.set $rf (ref.func $f))
+ (local.set $rg (ref.func $g))
+ (call_ref (call_ref (local.get $x) (local.get $rf)) (local.get $rg))
+ )
+
+ (func (export "null") (result i32)
+ (call_ref (i32.const 1) (ref.null $ii))
+ )
+
+ ;; Recursion
+
+ (type $ll (func (param i64) (result i64)))
+ (type $lll (func (param i64 i64) (result i64)))
+
+ (elem declare func $fac)
+ (global $fac (ref $ll) (ref.func $fac))
+
+ (func $fac (export "fac") (type $ll)
+ (if (result i64) (i64.eqz (local.get 0))
+ (then (i64.const 1))
+ (else
+ (i64.mul
+ (local.get 0)
+ (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
+ )
+ )
+ )
+ )
+
+ (elem declare func $fac-acc)
+ (global $fac-acc (ref $lll) (ref.func $fac-acc))
+
+ (func $fac-acc (export "fac-acc") (type $lll)
+ (if (result i64) (i64.eqz (local.get 0))
+ (then (local.get 1))
+ (else
+ (call_ref
+ (i64.sub (local.get 0) (i64.const 1))
+ (i64.mul (local.get 0) (local.get 1))
+ (global.get $fac-acc)
+ )
+ )
+ )
+ )
+
+ (elem declare func $fib)
+ (global $fib (ref $ll) (ref.func $fib))
+
+ (func $fib (export "fib") (type $ll)
+ (if (result i64) (i64.le_u (local.get 0) (i64.const 1))
+ (then (i64.const 1))
+ (else
+ (i64.add
+ (call_ref (i64.sub (local.get 0) (i64.const 2)) (global.get $fib))
+ (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fib))
+ )
+ )
+ )
+ )
+
+ (elem declare func $even $odd)
+ (global $even (ref $ll) (ref.func $even))
+ (global $odd (ref $ll) (ref.func $odd))
+
+ (func $even (export "even") (type $ll)
+ (if (result i64) (i64.eqz (local.get 0))
+ (then (i64.const 44))
+ (else (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $odd)))
+ )
+ )
+ (func $odd (export "odd") (type $ll)
+ (if (result i64) (i64.eqz (local.get 0))
+ (then (i64.const 99))
+ (else (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
+ )
+ )
+)
+
+(assert_return (invoke "run" (i32.const 0)) (i32.const 0))
+(assert_return (invoke "run" (i32.const 3)) (i32.const -9))
+
+(assert_trap (invoke "null") "null function")
+
+(assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
+(assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
+(assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
+(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
+(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
+(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
+(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
+(assert_return
+ (invoke "fac-acc" (i64.const 25) (i64.const 1))
+ (i64.const 7034535277573963776)
+)
+
+(assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
+(assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
+(assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
+(assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
+(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
+
+(assert_return (invoke "even" (i64.const 0)) (i64.const 44))
+(assert_return (invoke "even" (i64.const 1)) (i64.const 99))
+(assert_return (invoke "even" (i64.const 100)) (i64.const 44))
+(assert_return (invoke "even" (i64.const 77)) (i64.const 99))
+(assert_return (invoke "odd" (i64.const 0)) (i64.const 99))
+(assert_return (invoke "odd" (i64.const 1)) (i64.const 44))
+(assert_return (invoke "odd" (i64.const 200)) (i64.const 99))
+(assert_return (invoke "odd" (i64.const 77)) (i64.const 44))
+
+
+
+(assert_invalid
+ (module
+ (func $f (param $r externref)
+ (call_ref (local.get $r))
+ )
+ )
+ "type mismatch"
+)
diff --git a/test/spec/i31.wast b/test/spec/i31.wast
new file mode 100644
index 000000000..e413d3787
--- /dev/null
+++ b/test/spec/i31.wast
@@ -0,0 +1,30 @@
+(module
+ (func (export "new") (param $i i32) (result (ref i31))
+ (i31.new (local.get $i))
+ )
+
+ (func (export "get_u") (param $i i32) (result i32)
+ (i31.get_u (i31.new (local.get $i)))
+ )
+ (func (export "get_s") (param $i i32) (result i32)
+ (i31.get_s (i31.new (local.get $i)))
+ )
+)
+
+(assert_return (invoke "get_u" (i32.const 0)) (i32.const 0))
+(assert_return (invoke "get_u" (i32.const 100)) (i32.const 100))
+(assert_return (invoke "get_u" (i32.const -1)) (i32.const 0x7fffffff))
+(assert_return (invoke "get_u" (i32.const 0x3fffffff)) (i32.const 0x3fffffff))
+(assert_return (invoke "get_u" (i32.const 0x40000000)) (i32.const 0x40000000))
+(assert_return (invoke "get_u" (i32.const 0x7fffffff)) (i32.const 0x7fffffff))
+(assert_return (invoke "get_u" (i32.const 0xaaaaaaaa)) (i32.const 0x2aaaaaaa))
+(assert_return (invoke "get_u" (i32.const 0xcaaaaaaa)) (i32.const 0x4aaaaaaa))
+
+(assert_return (invoke "get_s" (i32.const 0)) (i32.const 0))
+(assert_return (invoke "get_s" (i32.const 100)) (i32.const 100))
+(assert_return (invoke "get_s" (i32.const -1)) (i32.const -1))
+(assert_return (invoke "get_s" (i32.const 0x3fffffff)) (i32.const 0x3fffffff))
+(assert_return (invoke "get_s" (i32.const 0x40000000)) (i32.const -0x40000000))
+(assert_return (invoke "get_s" (i32.const 0x7fffffff)) (i32.const -1))
+(assert_return (invoke "get_s" (i32.const 0xaaaaaaaa)) (i32.const 0x2aaaaaaa))
+(assert_return (invoke "get_s" (i32.const 0xcaaaaaaa)) (i32.const 0xcaaaaaaa))
diff --git a/test/spec/ref_as_non_null.wast b/test/spec/ref_as_non_null.wast
new file mode 100644
index 000000000..7e9417191
--- /dev/null
+++ b/test/spec/ref_as_non_null.wast
@@ -0,0 +1,28 @@
+(module
+ (type $t (func (result i32)))
+
+ (func $nn (param $r (ref $t)) (result i32)
+ (call_ref (ref.as_non_null (local.get $r)))
+ )
+ (func $n (param $r (ref null $t)) (result i32)
+ (call_ref (ref.as_non_null (local.get $r)))
+ )
+
+ (elem func $f)
+ (func $f (result i32) (i32.const 7))
+
+ (func (export "nullable-null") (result i32) (call $n (ref.null $t)))
+ (func (export "nonnullable-f") (result i32) (call $nn (ref.func $f)))
+ (func (export "nullable-f") (result i32) (call $n (ref.func $f)))
+)
+
+(assert_trap (invoke "nullable-null") "null reference")
+(assert_return (invoke "nonnullable-f") (i32.const 7))
+(assert_return (invoke "nullable-f") (i32.const 7))
+
+(module
+ (type $t (func))
+ (func (param $r (ref $t)) (drop (ref.as_non_null (local.get $r))))
+ (func (param $r (ref func)) (drop (ref.as_non_null (local.get $r))))
+ (func (param $r (ref extern)) (drop (ref.as_non_null (local.get $r))))
+)
diff --git a/test/spec/struct.wast b/test/spec/struct.wast
new file mode 100644
index 000000000..994b025d1
--- /dev/null
+++ b/test/spec/struct.wast
@@ -0,0 +1,98 @@
+;; Binding structure
+
+(module
+ (type $s0 (struct (field (ref 0) (ref 1) (ref $s0) (ref $s1))))
+ (type $s1 (struct (field (ref 0) (ref 1) (ref $s0) (ref $s1))))
+
+ (func (param (ref $forward)))
+
+ (type $forward (struct))
+)
+
+(assert_invalid
+ (module (type (struct (field (ref 1)))))
+ "unknown type"
+)
+(assert_invalid
+ (module (type (struct (field (mut (ref 1))))))
+ "unknown type"
+)
+
+
+;; Basic instructions
+
+(module
+ (type $vec (struct (field f32) (field $y (mut f32)) (field $z f32)))
+
+ (func $get_0 (param $v (ref $vec)) (result f32)
+ (struct.get $vec 0 (local.get $v))
+ )
+ (func (export "get_0") (result f32)
+ (call $get_0 (struct.new_default_with_rtt $vec (rtt.canon $vec)))
+ )
+
+ (func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32)
+ (struct.set $vec $y (local.get $v) (local.get $y))
+ (struct.get $vec $y (local.get $v))
+ )
+ (func (export "set_get_y") (param $y f32) (result f32)
+ (call $set_get_y (struct.new_default_with_rtt $vec (rtt.canon $vec)) (local.get $y))
+ )
+
+ (func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32)
+ (struct.set $vec 1 (local.get $v) (local.get $y))
+ (struct.get $vec $y (local.get $v))
+ )
+ (func (export "set_get_1") (param $y f32) (result f32)
+ (call $set_get_1 (struct.new_default_with_rtt $vec (rtt.canon $vec)) (local.get $y))
+ )
+)
+
+(assert_return (invoke "get_0") (f32.const 0))
+(assert_return (invoke "set_get_y" (f32.const 7)) (f32.const 7))
+(assert_return (invoke "set_get_1" (f32.const 7)) (f32.const 7))
+
+(assert_invalid
+ (module
+ (type $s (struct (field i64)))
+ (func (export "struct.set-immutable") (param $s (ref $s))
+ (struct.set $s 0 (local.get $s) (i64.const 1))
+ )
+ )
+ "field is immutable"
+)
+
+
+;; Null dereference
+
+(module
+ (type $t (struct (field i32) (field (mut i32))))
+ (func (export "struct.get-null")
+ (local (ref null $t)) (drop (struct.get $t 1 (local.get 0)))
+ )
+ (func (export "struct.set-null")
+ (local (ref null $t)) (struct.set $t 1 (local.get 0) (i32.const 0))
+ )
+)
+
+(assert_trap (invoke "struct.get-null") "null structure")
+(assert_trap (invoke "struct.set-null") "null structure")
+
+(assert_invalid
+ (module
+ (type $t (struct (field i32) (field (mut i32))))
+ (func (export "struct.new-null")
+ (local (ref null (rtt $t))) (drop (struct.new $t (i32.const 1) (i32.const 2) (local.get 0)))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (type $t (struct (field i32) (field (mut i32))))
+ (func (export "struct.new_default-null")
+ (local (ref null (rtt $t))) (drop (struct.new_default_with_rtt $t (local.get 0)))
+ )
+ )
+ "type mismatch"
+)