diff options
-rw-r--r-- | test/spec/call_ref.wast | 135 | ||||
-rw-r--r-- | test/spec/i31.wast | 30 | ||||
-rw-r--r-- | test/spec/ref_as_non_null.wast | 28 | ||||
-rw-r--r-- | test/spec/struct.wast | 98 |
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" +) |