diff --git a/binary-leb128.wast b/binary-leb128.wast index 1d67219..1b64226 100644 --- a/binary-leb128.wast +++ b/binary-leb128.wast @@ -290,7 +290,7 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" - "\01\08\01" ;; type section + "\01\0c\01" ;; type section "\60" ;; func type "\02" ;; num params "\7f\7e" ;; param type diff --git a/elem.wast b/elem.wast index af12fec..8dc04e6 100644 --- a/elem.wast +++ b/elem.wast @@ -600,3 +600,59 @@ (assert_return (invoke $module1 "call-7") (i32.const 67)) (assert_return (invoke $module1 "call-8") (i32.const 69)) (assert_return (invoke $module1 "call-9") (i32.const 70)) + +;; Element segments must match element type of table + +(assert_invalid + (module (func $f) (table 1 externref) (elem (i32.const 0) $f)) + "type mismatch" +) + +(assert_invalid + (module (table 1 funcref) (elem (i32.const 0) externref (ref.null extern))) + "type mismatch" +) + +(assert_invalid + (module + (func $f) + (table $t 1 externref) + (elem $e funcref (ref.func $f)) + (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1)))) + "type mismatch" +) + +(assert_invalid + (module + (table $t 1 funcref) + (elem $e externref (ref.null extern)) + (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1)))) + "type mismatch" +) + +;; Initializing a table with an externref-type element segment + +(module $m + (table $t (export "table") 2 externref) + (func (export "get") (param $i i32) (result externref) + (table.get $t (local.get $i))) + (func (export "set") (param $i i32) (param $x externref) + (table.set $t (local.get $i) (local.get $x)))) + +(register "exporter" $m) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.null extern)) + +(assert_return (invoke $m "set" (i32.const 0) (ref.extern 42))) +(assert_return (invoke $m "set" (i32.const 1) (ref.extern 137))) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.extern 42)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137)) + +(module + (import "exporter" "table" (table $t 2 externref)) + (elem (i32.const 0) externref (ref.null extern))) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137)) diff --git a/imports.wast b/imports.wast index 35e8c91..69f76a0 100644 --- a/imports.wast +++ b/imports.wast @@ -30,11 +30,9 @@ (type $func_f64 (func (param f64))) (import "spectest" "print_i32" (func (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (func (import "spectest" "print_i64") (param i64)) + (func (import "spectest" "print_i64") (param i64)) (import "spectest" "print_i32" (func $print_i32 (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "print_i64" (func $print_i64 (param i64))) + (import "spectest" "print_i64" (func $print_i64 (param i64))) (import "spectest" "print_f32" (func $print_f32 (param f32))) (import "spectest" "print_f64" (func $print_f64 (param f64))) (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) @@ -72,14 +70,12 @@ (func (export "print64") (param $i i64) (local $x f64) (local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i)))) - ;; JavaScript can't handle i64 yet. - ;; (call 1 (local.get $i)) + (call 1 (local.get $i)) (call $print_f64_f64 (f64.add (local.get $x) (f64.const 1)) (f64.const 53) ) - ;; JavaScript can't handle i64 yet. - ;; (call $print_i64 (local.get $i)) + (call $print_i64 (local.get $i)) (call $print_f64 (local.get $x)) (call $print_f64-2 (local.get $x)) (call_indirect (type $func_f64) (local.get $x) (i32.const 1)) @@ -234,8 +230,7 @@ (import "spectest" "global_i32" (global $x i32)) (global $y (import "spectest" "global_i32") i32) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "global_i64" (global i64)) + (import "spectest" "global_i64" (global i64)) (import "spectest" "global_f32" (global f32)) (import "spectest" "global_f64" (global f64)) diff --git a/proposals/exception-handling/imports.wast b/proposals/exception-handling/imports.wast index 167a578..74fbf71 100644 --- a/proposals/exception-handling/imports.wast +++ b/proposals/exception-handling/imports.wast @@ -34,11 +34,9 @@ (type $func_f64 (func (param f64))) (import "spectest" "print_i32" (func (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (func (import "spectest" "print_i64") (param i64)) + (func (import "spectest" "print_i64") (param i64)) (import "spectest" "print_i32" (func $print_i32 (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "print_i64" (func $print_i64 (param i64))) + (import "spectest" "print_i64" (func $print_i64 (param i64))) (import "spectest" "print_f32" (func $print_f32 (param f32))) (import "spectest" "print_f64" (func $print_f64 (param f64))) (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) @@ -79,14 +77,12 @@ (func (export "print64") (param $i i64) (local $x f64) (local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i)))) - ;; JavaScript can't handle i64 yet. - ;; (call 1 (local.get $i)) + (call 1 (local.get $i)) (call $print_f64_f64 (f64.add (local.get $x) (f64.const 1)) (f64.const 53) ) - ;; JavaScript can't handle i64 yet. - ;; (call $print_i64 (local.get $i)) + (call $print_i64 (local.get $i)) (call $print_f64 (local.get $x)) (call $print_f64-2 (local.get $x)) (call_indirect (type $func_f64) (local.get $x) (i32.const 1)) @@ -266,8 +262,7 @@ (import "spectest" "global_i32" (global $x i32)) (global $y (import "spectest" "global_i32") i32) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "global_i64" (global i64)) + (import "spectest" "global_i64" (global i64)) (import "spectest" "global_f32" (global f32)) (import "spectest" "global_f64" (global f64)) diff --git a/proposals/extended-const/elem.wast b/proposals/extended-const/elem.wast index 8547f80..9554fa9 100644 --- a/proposals/extended-const/elem.wast +++ b/proposals/extended-const/elem.wast @@ -601,3 +601,59 @@ (assert_return (invoke $module1 "call-7") (i32.const 67)) (assert_return (invoke $module1 "call-8") (i32.const 69)) (assert_return (invoke $module1 "call-9") (i32.const 70)) + +;; Element segments must match element type of table + +(assert_invalid + (module (func $f) (table 1 externref) (elem (i32.const 0) $f)) + "type mismatch" +) + +(assert_invalid + (module (table 1 funcref) (elem (i32.const 0) externref (ref.null extern))) + "type mismatch" +) + +(assert_invalid + (module + (func $f) + (table $t 1 externref) + (elem $e funcref (ref.func $f)) + (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1)))) + "type mismatch" +) + +(assert_invalid + (module + (table $t 1 funcref) + (elem $e externref (ref.null extern)) + (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1)))) + "type mismatch" +) + +;; Initializing a table with an externref-type element segment + +(module $m + (table $t (export "table") 2 externref) + (func (export "get") (param $i i32) (result externref) + (table.get $t (local.get $i))) + (func (export "set") (param $i i32) (param $x externref) + (table.set $t (local.get $i) (local.get $x)))) + +(register "exporter" $m) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.null extern)) + +(assert_return (invoke $m "set" (i32.const 0) (ref.extern 42))) +(assert_return (invoke $m "set" (i32.const 1) (ref.extern 137))) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.extern 42)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137)) + +(module + (import "exporter" "table" (table $t 2 externref)) + (elem (i32.const 0) externref (ref.null extern))) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137)) diff --git a/proposals/gc/array.wast b/proposals/gc/array.wast index be9a608..7ee75b2 100644 --- a/proposals/gc/array.wast +++ b/proposals/gc/array.wast @@ -8,11 +8,9 @@ (type (array f32)) (type (array f64)) (type (array anyref)) - (type (array (ref data))) + (type (array (ref struct))) (type (array (ref 0))) (type (array (ref null 1))) - (type (array (rtt 1))) - (type (array (rtt 10))) (type (array (mut i8))) (type (array (mut i16))) (type (array (mut i32))) @@ -20,11 +18,9 @@ (type (array (mut i32))) (type (array (mut i64))) (type (array (mut anyref))) - (type (array (mut (ref data)))) + (type (array (mut (ref struct)))) (type (array (mut (ref 0)))) (type (array (mut (ref null i31)))) - (type (array (mut (rtt 0)))) - (type (array (mut (rtt 10)))) ) @@ -65,11 +61,11 @@ (type $vec (array f32)) (type $mvec (array (mut f32))) - (global (ref $vec) (array.new $vec (f32.const 1) (i32.const 3) (rtt.canon $vec))) - (global (ref $vec) (array.new_default $vec (i32.const 3) (rtt.canon $vec))) + (global (ref $vec) (array.new_canon $vec (f32.const 1) (i32.const 3))) + (global (ref $vec) (array.new_canon_default $vec (i32.const 3))) (func $new (export "new") (result (ref $vec)) - (array.new_default $vec (i32.const 3) (rtt.canon $vec)) + (array.new_canon_default $vec (i32.const 3)) ) (func $get (param $i i32) (param $v (ref $vec)) (result f32) @@ -85,7 +81,7 @@ ) (func (export "set_get") (param $i i32) (param $y f32) (result f32) (call $set_get (local.get $i) - (array.new_default $mvec (i32.const 3) (rtt.canon $mvec)) + (array.new_canon_default $mvec (i32.const 3)) (local.get $y) ) ) @@ -99,7 +95,7 @@ ) (assert_return (invoke "new") (ref.array)) -(assert_return (invoke "new") (ref.data)) +(assert_return (invoke "new") (ref.eq)) (assert_return (invoke "get" (i32.const 0)) (f32.const 0)) (assert_return (invoke "set_get" (i32.const 1) (f32.const 7)) (f32.const 7)) (assert_return (invoke "len") (i32.const 3)) @@ -111,10 +107,10 @@ (type $vec (array f32)) (type $mvec (array (mut f32))) - (global (ref $vec) (array.new_fixed $vec 2 (f32.const 1) (f32.const 2) (rtt.canon $vec))) + (global (ref $vec) (array.new_canon_fixed $vec 2 (f32.const 1) (f32.const 2))) (func $new (export "new") (result (ref $vec)) - (array.new_fixed $vec 2 (f32.const 1) (f32.const 2) (rtt.canon $vec)) + (array.new_canon_fixed $vec 2 (f32.const 1) (f32.const 2)) ) (func $get (param $i i32) (param $v (ref $vec)) (result f32) @@ -130,7 +126,7 @@ ) (func (export "set_get") (param $i i32) (param $y f32) (result f32) (call $set_get (local.get $i) - (array.new_fixed $mvec 3 (f32.const 1) (f32.const 2) (f32.const 3) (rtt.canon $mvec)) + (array.new_canon_fixed $mvec 3 (f32.const 1) (f32.const 2) (f32.const 3)) (local.get $y) ) ) @@ -144,7 +140,7 @@ ) (assert_return (invoke "new") (ref.array)) -(assert_return (invoke "new") (ref.data)) +(assert_return (invoke "new") (ref.eq)) (assert_return (invoke "get" (i32.const 0)) (f32.const 1)) (assert_return (invoke "set_get" (i32.const 1) (f32.const 7)) (f32.const 7)) (assert_return (invoke "len") (i32.const 2)) @@ -159,7 +155,7 @@ (data $d "\00\01\02\03\04") (func $new (export "new") (result (ref $vec)) - (array.new_data $vec $d (i32.const 1) (i32.const 3) (rtt.canon $vec)) + (array.new_canon_data $vec $d (i32.const 1) (i32.const 3)) ) (func $get (param $i i32) (param $v (ref $vec)) (result i32) @@ -175,7 +171,7 @@ ) (func (export "set_get") (param $i i32) (param $y i32) (result i32) (call $set_get (local.get $i) - (array.new_data $mvec $d (i32.const 1) (i32.const 3) (rtt.canon $mvec)) + (array.new_canon_data $mvec $d (i32.const 1) (i32.const 3)) (local.get $y) ) ) @@ -189,7 +185,7 @@ ) (assert_return (invoke "new") (ref.array)) -(assert_return (invoke "new") (ref.data)) +(assert_return (invoke "new") (ref.eq)) (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)) @@ -205,19 +201,19 @@ (type $avec (array (mut anyref))) (elem $e (ref $bvec) - (array.new $bvec (i32.const 7) (i32.const 3) (rtt.canon $bvec)) - (array.new_fixed $bvec 2 (i32.const 1) (i32.const 2) (rtt.canon $bvec)) + (array.new_canon $bvec (i32.const 7) (i32.const 3)) + (array.new_canon_fixed $bvec 2 (i32.const 1) (i32.const 2)) ) (func $new (export "new") (result (ref $vec)) - (array.new_elem $vec $e (i32.const 0) (i32.const 2) (rtt.canon $vec)) + (array.new_canon_elem $vec $e (i32.const 0) (i32.const 2)) ) (func $sub1 (result (ref $nvec)) - (array.new_elem $nvec $e (i32.const 0) (i32.const 2) (rtt.canon $nvec)) + (array.new_canon_elem $nvec $e (i32.const 0) (i32.const 2)) ) (func $sub2 (result (ref $avec)) - (array.new_elem $avec $e (i32.const 0) (i32.const 2) (rtt.canon $avec)) + (array.new_canon_elem $avec $e (i32.const 0) (i32.const 2)) ) (func $get (param $i i32) (param $j i32) (param $v (ref $vec)) (result i32) @@ -233,7 +229,7 @@ ) (func (export "set_get") (param $i i32) (param $j i32) (param $y i32) (result i32) (call $set_get (local.get $i) (local.get $j) - (array.new_elem $mvec $e (i32.const 0) (i32.const 2) (rtt.canon $mvec)) + (array.new_canon_elem $mvec $e (i32.const 0) (i32.const 2)) (local.get $y) ) ) @@ -247,7 +243,7 @@ ) (assert_return (invoke "new") (ref.array)) -(assert_return (invoke "new") (ref.data)) +(assert_return (invoke "new") (ref.eq)) (assert_return (invoke "get" (i32.const 0) (i32.const 0)) (i32.const 7)) (assert_return (invoke "get" (i32.const 1) (i32.const 0)) (i32.const 1)) (assert_return (invoke "set_get" (i32.const 0) (i32.const 1) (i32.const 1)) (i32.const 2)) @@ -273,7 +269,7 @@ (data $d "\00\01\02\03\04") (global (ref $bvec) - (array.new_data $bvec $d (i32.const 1) (i32.const 3) (rtt.canon $bvec)) + (array.new_canon_data $bvec $d (i32.const 1) (i32.const 3)) ) ) "constant expression required" @@ -287,7 +283,7 @@ (elem $e (ref $bvec) (ref.null $bvec)) (global (ref $vvec) - (array.new_elem $vvec $e (i32.const 0) (i32.const 1) (rtt.canon $vvec)) + (array.new_canon_elem $vvec $e (i32.const 0) (i32.const 1)) ) ) "constant expression required" @@ -308,22 +304,3 @@ (assert_trap (invoke "array.get-null") "null array") (assert_trap (invoke "array.set-null") "null array") - -(assert_invalid - (module - (type $t (array i32)) - (func (export "array.new-null") - (local (ref null (rtt $t))) (drop (array.new_default $t (i32.const 1) (i32.const 3) (local.get 0))) - ) - ) - "type mismatch" -) -(assert_invalid - (module - (type $t (array (mut i32))) - (func (export "array.new_default-null") - (local (ref null (rtt $t))) (drop (array.new_default $t (i32.const 3) (local.get 0))) - ) - ) - "type mismatch" -) diff --git a/proposals/gc/binary.wast b/proposals/gc/binary.wast index 843b7db..84f4b15 100644 --- a/proposals/gc/binary.wast +++ b/proposals/gc/binary.wast @@ -140,23 +140,68 @@ "\41\00\0b\00" ;; (i32.const 0) with no elements ) -;; Data segment memory index can have non-minimal length +;; Data segment tags and memory index can have non-minimal length (module binary "\00asm" "\01\00\00\00" "\05\03\01" ;; Memory section with 1 entry "\00\00" ;; no max, minimum 0 "\0b\07\01" ;; Data section with 1 entry - "\80\00" ;; Memory index 0, encoded with 2 bytes + "\80\00" ;; Active segment, encoded with 2 bytes + "\41\00\0b\00" ;; (i32.const 0) with contents "" +) +(module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; Memory section with 1 entry + "\00\00" ;; no max, minimum 0 + "\0b\08\01" ;; Data section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\00" ;; explicit memory index + "\41\00\0b\00" ;; (i32.const 0) with contents "" +) +(module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; Memory section with 1 entry + "\00\00" ;; no max, minimum 0 + "\0b\09\01" ;; Data section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\80\00" ;; explicit memory index, encoded with 2 bytes "\41\00\0b\00" ;; (i32.const 0) with contents "" ) -;; Element segment table index can have non-minimal length +;; Element segment tags and table index can have non-minimal length +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\07\01" ;; Element section with 1 entry + "\80\00" ;; Active segment + "\41\00\0b\00" ;; (i32.const 0) with no elements +) (module binary "\00asm" "\01\00\00\00" "\04\04\01" ;; Table section with 1 entry "\70\00\00" ;; no max, minimum 0, funcref "\09\09\01" ;; Element section with 1 entry - "\02\80\00" ;; Table index 0, encoded with 2 bytes + "\02" ;; Active segment + "\80\00" ;; explicit table index, encoded with 2 bytes + "\41\00\0b\00\00" ;; (i32.const 0) with no elements +) +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\09\01" ;; Element section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\00" ;; explicit table index + "\41\00\0b\00\00" ;; (i32.const 0) with no elements +) +(module binary + "\00asm" "\01\00\00\00" + "\04\04\01" ;; Table section with 1 entry + "\70\00\00" ;; no max, minimum 0, funcref + "\09\0a\01" ;; Element section with 1 entry + "\82\00" ;; Active segment, encoded with 2 bytes + "\80\00" ;; explicit table index, encoded with 2 bytes "\41\00\0b\00\00" ;; (i32.const 0) with no elements ) @@ -1196,7 +1241,7 @@ ) ;; end "data count section required") -;; passive element segment containing opcode other than ref.func or ref.null +;; passive element segment containing illegal opcode (assert_malformed (module binary "\00asm" "\01\00\00\00" @@ -1213,7 +1258,7 @@ "\09\07\01" ;; Element section with one segment "\05\70" ;; Passive, funcref "\01" ;; 1 element - "\ff\00\0b" ;; bad opcode, index 0, end + "\f3\00\0b" ;; bad opcode, index 0, end "\0a\04\01" ;; Code section diff --git a/proposals/gc/br_on.wast b/proposals/gc/br_on.wast deleted file mode 100644 index 16da9b9..0000000 --- a/proposals/gc/br_on.wast +++ /dev/null @@ -1,107 +0,0 @@ -(module - (type $ft (func (result i32))) - (type $st (struct (field i16))) - (type $at (array i8)) - - (table 10 anyref) - - (elem declare func $f) - (func $f (result i32) (i32.const 9)) - - (func (export "init") (param $x externref) - (table.set (i32.const 0) (ref.null any)) - (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new $st (i32.const 6) (rtt.canon $st))) - (table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 3) (rtt.canon $at))) - (table.set (i32.const 4) (ref.func $f)) - (table.set (i32.const 5) (rtt.canon $ft)) - (table.set (i32.const 6) (local.get $x)) - ) - - (func (export "br_on_null") (param $i i32) (result i32) - (block $l - (br_on_null $l (table.get (local.get $i))) - (return (i32.const -1)) - ) - (i32.const 0) - ) - (func (export "br_on_i31") (param $i i32) (result i32) - (block $l (result (ref i31)) - (br_on_i31 $l (table.get (local.get $i))) - (return (i32.const -1)) - ) - (i31.get_u) - ) - (func (export "br_on_data") (param $i i32) (result i32) - (block $l (result (ref data)) - (br_on_data $l (table.get (local.get $i))) - (return (i32.const -1)) - ) - (block $l2 (param dataref) (result (ref $st)) - (block $l3 (param dataref) (result (ref $at)) - (br_on_cast $l2 (rtt.canon $st)) - (br_on_cast $l3 (rtt.canon $at)) - (return (i32.const -2)) - ) - (return (array.get_u $at (i32.const 0))) - ) - (struct.get_s $st 0) - ) - (func (export "br_on_array") (param $i i32) (result i32) - (block $l (result (ref array)) - (br_on_array $l (table.get (local.get $i))) - (return (i32.const -1)) - ) - (array.len) - ) - (func (export "br_on_func") (param $i i32) (result i32) - (block $l (result (ref func)) - (br_on_func $l (table.get (local.get $i))) - (return (i32.const -1)) - ) - (ref.cast (rtt.canon $ft)) - (call_ref) - ) -) - -(invoke "init" (ref.extern 0)) - -(assert_return (invoke "br_on_null" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "br_on_null" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_null" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_null" (i32.const 3)) (i32.const -1)) -(assert_return (invoke "br_on_null" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_null" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_null" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_i31" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_i31" (i32.const 1)) (i32.const 7)) -(assert_return (invoke "br_on_i31" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_i31" (i32.const 3)) (i32.const -1)) -(assert_return (invoke "br_on_i31" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_i31" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_i31" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_data" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_data" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_data" (i32.const 2)) (i32.const 6)) -(assert_return (invoke "br_on_data" (i32.const 3)) (i32.const 5)) -(assert_return (invoke "br_on_data" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_data" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_data" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_array" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_array" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_array" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_array" (i32.const 3)) (i32.const 3)) -(assert_return (invoke "br_on_array" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_array" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_array" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_func" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_func" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_func" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_func" (i32.const 3)) (i32.const -1)) -(assert_return (invoke "br_on_func" (i32.const 4)) (i32.const 9)) -(assert_return (invoke "br_on_func" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_func" (i32.const 6)) (i32.const -1)) diff --git a/proposals/gc/br_on_cast.wast b/proposals/gc/br_on_cast.wast index 20f7e08..fd191da 100644 --- a/proposals/gc/br_on_cast.wast +++ b/proposals/gc/br_on_cast.wast @@ -1,3 +1,90 @@ +;; Abstract Types + +(module + (type $ft (func (result i32))) + (type $st (struct (field i16))) + (type $at (array i8)) + + (table 10 anyref) + + (elem declare func $f) + (func $f (result i32) (i32.const 9)) + + (func (export "init") (param $x externref) + (table.set (i32.const 0) (ref.null any)) + (table.set (i32.const 1) (i31.new (i32.const 7))) + (table.set (i32.const 2) (struct.new_canon $st (i32.const 6))) + (table.set (i32.const 3) (array.new_canon $at (i32.const 5) (i32.const 3))) + (table.set (i32.const 4) (extern.internalize (local.get $x))) + ) + + (func (export "br_on_null") (param $i i32) (result i32) + (block $l + (br_on_null $l (table.get (local.get $i))) + (return (i32.const -1)) + ) + (i32.const 0) + ) + (func (export "br_on_i31") (param $i i32) (result i32) + (block $l (result (ref i31)) + (br_on_cast $l i31 (table.get (local.get $i))) + (return (i32.const -1)) + ) + (i31.get_u) + ) + (func (export "br_on_struct") (param $i i32) (result i32) + (block $l (result (ref struct)) + (br_on_cast $l struct (table.get (local.get $i))) + (return (i32.const -1)) + ) + (block $l2 (param structref) (result (ref $st)) + (block $l3 (param structref) (result (ref $at)) + (br_on_cast $l2 $st) + (br_on_cast $l3 $at) + (return (i32.const -2)) + ) + (return (array.get_u $at (i32.const 0))) + ) + (struct.get_s $st 0) + ) + (func (export "br_on_array") (param $i i32) (result i32) + (block $l (result (ref array)) + (br_on_cast $l array (table.get (local.get $i))) + (return (i32.const -1)) + ) + (array.len) + ) +) + +(invoke "init" (ref.extern 0)) + +(assert_return (invoke "br_on_null" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "br_on_null" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "br_on_null" (i32.const 2)) (i32.const -1)) +(assert_return (invoke "br_on_null" (i32.const 3)) (i32.const -1)) +(assert_return (invoke "br_on_null" (i32.const 4)) (i32.const -1)) + +(assert_return (invoke "br_on_i31" (i32.const 0)) (i32.const -1)) +(assert_return (invoke "br_on_i31" (i32.const 1)) (i32.const 7)) +(assert_return (invoke "br_on_i31" (i32.const 2)) (i32.const -1)) +(assert_return (invoke "br_on_i31" (i32.const 3)) (i32.const -1)) +(assert_return (invoke "br_on_i31" (i32.const 4)) (i32.const -1)) + +(assert_return (invoke "br_on_struct" (i32.const 0)) (i32.const -1)) +(assert_return (invoke "br_on_struct" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "br_on_struct" (i32.const 2)) (i32.const 6)) +(assert_return (invoke "br_on_struct" (i32.const 3)) (i32.const -1)) +(assert_return (invoke "br_on_struct" (i32.const 4)) (i32.const -1)) + +(assert_return (invoke "br_on_array" (i32.const 0)) (i32.const -1)) +(assert_return (invoke "br_on_array" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "br_on_array" (i32.const 2)) (i32.const -1)) +(assert_return (invoke "br_on_array" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "br_on_array" (i32.const 4)) (i32.const -1)) + + +;; Concrete Types + (module (type $t0 (struct)) (type $t1 (sub $t0 (struct (field i32)))) @@ -8,71 +95,62 @@ (type $t0' (sub $t0 (struct))) (type $t4 (sub $t0' (struct (field i32 i32)))) - (global $t0 (rtt $t0) (rtt.canon $t0)) - (global $t0' (rtt $t0) (rtt.canon $t0)) - (global $t1 (rtt $t1) (rtt.canon $t1)) - (global $t1' (rtt $t1') (rtt.canon $t1')) - (global $t2 (rtt $t2) (rtt.canon $t2)) - (global $t2' (rtt $t2') (rtt.canon $t2')) - (global $t3 (rtt $t3) (rtt.canon $t3)) - (global $t4 (rtt $t4) (rtt.canon $t4)) - - (table 20 dataref) + (table 20 structref) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t4 (global.get $t4))) + (table.set (i32.const 0) (struct.new_canon_default $t0)) + (table.set (i32.const 10) (struct.new_canon_default $t0')) + (table.set (i32.const 1) (struct.new_canon_default $t1)) + (table.set (i32.const 11) (struct.new_canon_default $t1')) + (table.set (i32.const 2) (struct.new_canon_default $t2)) + (table.set (i32.const 12) (struct.new_canon_default $t2')) + (table.set (i32.const 3) (struct.new_canon_default $t3)) + (table.set (i32.const 4) (struct.new_canon_default $t4)) ) (func (export "test-sub") (call $init) - (block $l (result dataref) + (block $l (result structref) ;; must succeed - (drop (block (result dataref) (br_on_cast 0 (ref.null data) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 0)) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 1)) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 2)) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 3)) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 4)) (global.get $t0)))) + (drop (block (result structref) (br_on_cast 0 $t0 (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 4))))) - (drop (block (result dataref) (br_on_cast 0 (ref.null data) (global.get $t1)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 1)) (global.get $t1)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 2)) (global.get $t1)))) + (drop (block (result structref) (br_on_cast 0 $t1 (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 2))))) - (drop (block (result dataref) (br_on_cast 0 (ref.null data) (global.get $t2)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 2)) (global.get $t2)))) + (drop (block (result structref) (br_on_cast 0 $t2 (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 $t2 (table.get (i32.const 2))))) - (drop (block (result dataref) (br_on_cast 0 (ref.null data) (global.get $t3)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 3)) (global.get $t3)))) + (drop (block (result structref) (br_on_cast 0 $t3 (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 $t3 (table.get (i32.const 3))))) - (drop (block (result dataref) (br_on_cast 0 (ref.null data) (global.get $t4)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 4)) (global.get $t4)))) + (drop (block (result structref) (br_on_cast 0 $t4 (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 $t4 (table.get (i32.const 4))))) ;; must not succeed - (br_on_cast $l (table.get (i32.const 0)) (global.get $t1)) - (br_on_cast $l (table.get (i32.const 3)) (global.get $t1)) - (br_on_cast $l (table.get (i32.const 4)) (global.get $t1)) + (br_on_cast $l $t1 (table.get (i32.const 0))) + (br_on_cast $l $t1 (table.get (i32.const 3))) + (br_on_cast $l $t1 (table.get (i32.const 4))) - (br_on_cast $l (table.get (i32.const 0)) (global.get $t2)) - (br_on_cast $l (table.get (i32.const 1)) (global.get $t2)) - (br_on_cast $l (table.get (i32.const 3)) (global.get $t2)) - (br_on_cast $l (table.get (i32.const 4)) (global.get $t2)) + (br_on_cast $l $t2 (table.get (i32.const 0))) + (br_on_cast $l $t2 (table.get (i32.const 1))) + (br_on_cast $l $t2 (table.get (i32.const 3))) + (br_on_cast $l $t2 (table.get (i32.const 4))) - (br_on_cast $l (table.get (i32.const 0)) (global.get $t3)) - (br_on_cast $l (table.get (i32.const 1)) (global.get $t3)) - (br_on_cast $l (table.get (i32.const 2)) (global.get $t3)) - (br_on_cast $l (table.get (i32.const 4)) (global.get $t3)) + (br_on_cast $l $t3 (table.get (i32.const 0))) + (br_on_cast $l $t3 (table.get (i32.const 1))) + (br_on_cast $l $t3 (table.get (i32.const 2))) + (br_on_cast $l $t3 (table.get (i32.const 4))) - (br_on_cast $l (table.get (i32.const 0)) (global.get $t4)) - (br_on_cast $l (table.get (i32.const 1)) (global.get $t4)) - (br_on_cast $l (table.get (i32.const 2)) (global.get $t4)) - (br_on_cast $l (table.get (i32.const 3)) (global.get $t4)) + (br_on_cast $l $t4 (table.get (i32.const 0))) + (br_on_cast $l $t4 (table.get (i32.const 1))) + (br_on_cast $l $t4 (table.get (i32.const 2))) + (br_on_cast $l $t4 (table.get (i32.const 3))) (return) ) @@ -82,25 +160,25 @@ (func (export "test-canon") (call $init) (block $l - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 0)) (global.get $t0')))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 1)) (global.get $t0')))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 2)) (global.get $t0')))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 3)) (global.get $t0')))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 4)) (global.get $t0')))) + (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 4))))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 10)) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 11)) (global.get $t0)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 12)) (global.get $t0)))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 10))))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 11))))) + (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 12))))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 1)) (global.get $t1')))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 2)) (global.get $t1')))) + (drop (block (result structref) (br_on_cast 0 $t1' (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 $t1' (table.get (i32.const 2))))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 11)) (global.get $t1)))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 12)) (global.get $t1)))) + (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 11))))) + (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 12))))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 2)) (global.get $t2')))) + (drop (block (result structref) (br_on_cast 0 $t2' (table.get (i32.const 2))))) - (drop (block (result dataref) (br_on_cast 0 (table.get (i32.const 12)) (global.get $t2)))) + (drop (block (result structref) (br_on_cast 0 $t2 (table.get (i32.const 12))))) (return) ) diff --git a/proposals/gc/br_on_cast_fail.wast b/proposals/gc/br_on_cast_fail.wast index 62ff5e5..5c5199a 100644 --- a/proposals/gc/br_on_cast_fail.wast +++ b/proposals/gc/br_on_cast_fail.wast @@ -1,3 +1,90 @@ +;; Abstract Types + +(module + (type $ft (func (result i32))) + (type $st (struct (field i16))) + (type $at (array i8)) + + (table 10 anyref) + + (elem declare func $f) + (func $f (result i32) (i32.const 9)) + + (func (export "init") (param $x externref) + (table.set (i32.const 0) (ref.null any)) + (table.set (i32.const 1) (i31.new (i32.const 7))) + (table.set (i32.const 2) (struct.new_canon $st (i32.const 6))) + (table.set (i32.const 3) (array.new_canon $at (i32.const 5) (i32.const 3))) + (table.set (i32.const 4) (extern.internalize (local.get $x))) + ) + + (func (export "br_on_non_null") (param $i i32) (result i32) + (block $l (result (ref any)) + (br_on_non_null $l (table.get (local.get $i))) + (return (i32.const 0)) + ) + (return (i32.const -1)) + ) + (func (export "br_on_non_i31") (param $i i32) (result i32) + (block $l (result anyref) + (br_on_cast_fail $l i31 (table.get (local.get $i))) + (return (i31.get_u)) + ) + (return (i32.const -1)) + ) + (func (export "br_on_non_struct") (param $i i32) (result i32) + (block $l (result anyref) + (br_on_cast_fail $l struct (table.get (local.get $i))) + (block $l2 (param structref) (result (ref $st)) + (block $l3 (param structref) (result (ref $at)) + (br_on_cast $l2 $st) + (br_on_cast $l3 $at) + (return (i32.const -2)) + ) + (return (array.get_u $at (i32.const 0))) + ) + (return (struct.get_s $st 0)) + ) + (return (i32.const -1)) + ) + (func (export "br_on_non_array") (param $i i32) (result i32) + (block $l (result anyref) + (br_on_cast_fail $l array (table.get (local.get $i))) + (return (array.len)) + ) + (return (i32.const -1)) + ) +) + +(invoke "init" (ref.extern 0)) + +(assert_return (invoke "br_on_non_null" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "br_on_non_null" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "br_on_non_null" (i32.const 2)) (i32.const -1)) +(assert_return (invoke "br_on_non_null" (i32.const 3)) (i32.const -1)) +(assert_return (invoke "br_on_non_null" (i32.const 4)) (i32.const -1)) + +(assert_return (invoke "br_on_non_i31" (i32.const 0)) (i32.const -1)) +(assert_return (invoke "br_on_non_i31" (i32.const 1)) (i32.const 7)) +(assert_return (invoke "br_on_non_i31" (i32.const 2)) (i32.const -1)) +(assert_return (invoke "br_on_non_i31" (i32.const 3)) (i32.const -1)) +(assert_return (invoke "br_on_non_i31" (i32.const 4)) (i32.const -1)) + +(assert_return (invoke "br_on_non_struct" (i32.const 0)) (i32.const -1)) +(assert_return (invoke "br_on_non_struct" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "br_on_non_struct" (i32.const 2)) (i32.const 6)) +(assert_return (invoke "br_on_non_struct" (i32.const 3)) (i32.const -1)) +(assert_return (invoke "br_on_non_struct" (i32.const 4)) (i32.const -1)) + +(assert_return (invoke "br_on_non_array" (i32.const 0)) (i32.const -1)) +(assert_return (invoke "br_on_non_array" (i32.const 1)) (i32.const -1)) +(assert_return (invoke "br_on_non_array" (i32.const 2)) (i32.const -1)) +(assert_return (invoke "br_on_non_array" (i32.const 3)) (i32.const 3)) +(assert_return (invoke "br_on_non_array" (i32.const 4)) (i32.const -1)) + + +;; Concrete Types + (module (type $t0 (struct)) (type $t1 (sub $t0 (struct (field i32)))) @@ -8,71 +95,78 @@ (type $t0' (sub $t0 (struct))) (type $t4 (sub $t0' (struct (field i32 i32)))) - (global $t0 (rtt $t0) (rtt.canon $t0)) - (global $t0' (rtt $t0) (rtt.canon $t0)) - (global $t1 (rtt $t1) (rtt.canon $t1)) - (global $t1' (rtt $t1') (rtt.canon $t1')) - (global $t2 (rtt $t2) (rtt.canon $t2)) - (global $t2' (rtt $t2') (rtt.canon $t2')) - (global $t3 (rtt $t3) (rtt.canon $t3)) - (global $t4 (rtt $t4) (rtt.canon $t4)) - - (table 20 dataref) + (table 20 structref) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t4 (global.get $t4))) + (table.set (i32.const 0) (struct.new_canon_default $t0)) + (table.set (i32.const 10) (struct.new_canon_default $t0)) + (table.set (i32.const 1) (struct.new_canon_default $t1)) + (table.set (i32.const 11) (struct.new_canon_default $t1')) + (table.set (i32.const 2) (struct.new_canon_default $t2)) + (table.set (i32.const 12) (struct.new_canon_default $t2')) + (table.set (i32.const 3) (struct.new_canon_default $t3 )) + (table.set (i32.const 4) (struct.new_canon_default $t4)) ) (func (export "test-sub") (call $init) - (block $l (result dataref) + (block $l (result structref) ;; must not succeed - (br_on_cast_fail $l (ref.null data) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 0)) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 1)) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 2)) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 3)) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 4)) (global.get $t0)) - - (br_on_cast_fail $l (ref.null data) (global.get $t1)) - (br_on_cast_fail $l (table.get (i32.const 1)) (global.get $t1)) - (br_on_cast_fail $l (table.get (i32.const 2)) (global.get $t1)) - - (br_on_cast_fail $l (ref.null data) (global.get $t2)) - (br_on_cast_fail $l (table.get (i32.const 2)) (global.get $t2)) - - (br_on_cast_fail $l (ref.null data) (global.get $t3)) - (br_on_cast_fail $l (table.get (i32.const 3)) (global.get $t3)) - - (br_on_cast_fail $l (ref.null data) (global.get $t4)) - (br_on_cast_fail $l (table.get (i32.const 4)) (global.get $t4)) + (br_on_cast_fail $l null $t0 (ref.null struct)) + (br_on_cast_fail $l null $t0 (table.get (i32.const 0))) + (br_on_cast_fail $l null $t0 (table.get (i32.const 1))) + (br_on_cast_fail $l null $t0 (table.get (i32.const 2))) + (br_on_cast_fail $l null $t0 (table.get (i32.const 3))) + (br_on_cast_fail $l null $t0 (table.get (i32.const 4))) + (br_on_cast_fail $l $t0 (table.get (i32.const 0))) + (br_on_cast_fail $l $t0 (table.get (i32.const 1))) + (br_on_cast_fail $l $t0 (table.get (i32.const 2))) + (br_on_cast_fail $l $t0 (table.get (i32.const 3))) + (br_on_cast_fail $l $t0 (table.get (i32.const 4))) + + (br_on_cast_fail $l null $t1 (ref.null struct)) + (br_on_cast_fail $l null $t1 (table.get (i32.const 1))) + (br_on_cast_fail $l null $t1 (table.get (i32.const 2))) + (br_on_cast_fail $l $t1 (table.get (i32.const 1))) + (br_on_cast_fail $l $t1 (table.get (i32.const 2))) + + (br_on_cast_fail $l null $t2 (ref.null struct)) + (br_on_cast_fail $l null $t2 (table.get (i32.const 2))) + (br_on_cast_fail $l $t2 (table.get (i32.const 2))) + + (br_on_cast_fail $l null $t3 (ref.null struct)) + (br_on_cast_fail $l null $t3 (table.get (i32.const 3))) + (br_on_cast_fail $l $t3 (table.get (i32.const 3))) + + (br_on_cast_fail $l null $t4 (ref.null struct)) + (br_on_cast_fail $l null $t4 (table.get (i32.const 4))) + (br_on_cast_fail $l $t4 (table.get (i32.const 4))) ;; must succeed - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 0)) (global.get $t1)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 3)) (global.get $t1)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 4)) (global.get $t1)))) - - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 0)) (global.get $t2)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 1)) (global.get $t2)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 3)) (global.get $t2)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 4)) (global.get $t2)))) - - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 0)) (global.get $t3)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 1)) (global.get $t3)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 2)) (global.get $t3)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 4)) (global.get $t3)))) - - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 0)) (global.get $t4)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 1)) (global.get $t4)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 2)) (global.get $t4)))) - (drop (block (result dataref) (br_on_cast_fail 0 (table.get (i32.const 3)) (global.get $t4)))) + (drop (block (result structref) (br_on_cast_fail 0 $t0 (ref.null struct)))) + + (drop (block (result structref) (br_on_cast_fail 0 $t1 (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 $t1 (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 $t1 (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast_fail 0 $t1 (table.get (i32.const 4))))) + + (drop (block (result structref) (br_on_cast_fail 0 $t2 (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 4))))) + + (drop (block (result structref) (br_on_cast_fail 0 $t3 (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 4))))) + + (drop (block (result structref) (br_on_cast_fail 0 $t4 (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 3))))) (return) ) @@ -81,26 +175,25 @@ (func (export "test-canon") (call $init) - (block $l (result dataref) - (br_on_cast_fail $l (table.get (i32.const 0)) (global.get $t0')) - (br_on_cast_fail $l (table.get (i32.const 1)) (global.get $t0')) - (br_on_cast_fail $l (table.get (i32.const 2)) (global.get $t0')) - (br_on_cast_fail $l (table.get (i32.const 3)) (global.get $t0')) - (br_on_cast_fail $l (table.get (i32.const 4)) (global.get $t0')) - - (br_on_cast_fail $l (table.get (i32.const 10)) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 11)) (global.get $t0)) - (br_on_cast_fail $l (table.get (i32.const 12)) (global.get $t0)) + (block $l (result structref) + (br_on_cast_fail $l $t0 (table.get (i32.const 0))) + (br_on_cast_fail $l $t0 (table.get (i32.const 1))) + (br_on_cast_fail $l $t0 (table.get (i32.const 2))) + (br_on_cast_fail $l $t0 (table.get (i32.const 3))) + (br_on_cast_fail $l $t0 (table.get (i32.const 4))) + (br_on_cast_fail $l $t0 (table.get (i32.const 10))) + (br_on_cast_fail $l $t0 (table.get (i32.const 11))) + (br_on_cast_fail $l $t0 (table.get (i32.const 12))) - (br_on_cast_fail $l (table.get (i32.const 1)) (global.get $t1')) - (br_on_cast_fail $l (table.get (i32.const 2)) (global.get $t1')) + (br_on_cast_fail $l $t1' (table.get (i32.const 1))) + (br_on_cast_fail $l $t1' (table.get (i32.const 2))) - (br_on_cast_fail $l (table.get (i32.const 11)) (global.get $t1)) - (br_on_cast_fail $l (table.get (i32.const 12)) (global.get $t1)) + (br_on_cast_fail $l $t1 (table.get (i32.const 11))) + (br_on_cast_fail $l $t1 (table.get (i32.const 12))) - (br_on_cast_fail $l (table.get (i32.const 2)) (global.get $t2')) + (br_on_cast_fail $l $t2' (table.get (i32.const 2))) - (br_on_cast_fail $l (table.get (i32.const 12)) (global.get $t2)) + (br_on_cast_fail $l $t2 (table.get (i32.const 12))) (return) ) diff --git a/proposals/gc/br_on_non.wast b/proposals/gc/br_on_non.wast deleted file mode 100644 index c69e5e4..0000000 --- a/proposals/gc/br_on_non.wast +++ /dev/null @@ -1,107 +0,0 @@ -(module - (type $ft (func (result i32))) - (type $st (struct (field i16))) - (type $at (array i8)) - - (table 10 anyref) - - (elem declare func $f) - (func $f (result i32) (i32.const 9)) - - (func (export "init") (param $x externref) - (table.set (i32.const 0) (ref.null any)) - (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new $st (i32.const 6) (rtt.canon $st))) - (table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 3) (rtt.canon $at))) - (table.set (i32.const 4) (ref.func $f)) - (table.set (i32.const 5) (rtt.canon $ft)) - (table.set (i32.const 6) (local.get $x)) - ) - - (func (export "br_on_non_null") (param $i i32) (result i32) - (block $l (result (ref any)) - (br_on_non_null $l (table.get (local.get $i))) - (return (i32.const 0)) - ) - (return (i32.const -1)) - ) - (func (export "br_on_non_i31") (param $i i32) (result i32) - (block $l (result anyref) - (br_on_non_i31 $l (table.get (local.get $i))) - (return (i31.get_u)) - ) - (return (i32.const -1)) - ) - (func (export "br_on_non_data") (param $i i32) (result i32) - (block $l (result anyref) - (br_on_non_data $l (table.get (local.get $i))) - (block $l2 (param dataref) (result (ref $st)) - (block $l3 (param dataref) (result (ref $at)) - (br_on_cast $l2 (rtt.canon $st)) - (br_on_cast $l3 (rtt.canon $at)) - (return (i32.const -2)) - ) - (return (array.get_u $at (i32.const 0))) - ) - (return (struct.get_s $st 0)) - ) - (return (i32.const -1)) - ) - (func (export "br_on_non_array") (param $i i32) (result i32) - (block $l (result anyref) - (br_on_non_array $l (table.get (local.get $i))) - (return (array.len)) - ) - (return (i32.const -1)) - ) - (func (export "br_on_non_func") (param $i i32) (result i32) - (block $l (result anyref) - (br_on_non_func $l (table.get (local.get $i))) - (ref.cast (rtt.canon $ft)) - (return (call_ref)) - ) - (return (i32.const -1)) - ) -) - -(invoke "init" (ref.extern 0)) - -(assert_return (invoke "br_on_non_null" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "br_on_non_null" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_non_null" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_non_null" (i32.const 3)) (i32.const -1)) -(assert_return (invoke "br_on_non_null" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_non_null" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_non_null" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_non_i31" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_non_i31" (i32.const 1)) (i32.const 7)) -(assert_return (invoke "br_on_non_i31" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_non_i31" (i32.const 3)) (i32.const -1)) -(assert_return (invoke "br_on_non_i31" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_non_i31" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_non_i31" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_non_data" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_non_data" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_non_data" (i32.const 2)) (i32.const 6)) -(assert_return (invoke "br_on_non_data" (i32.const 3)) (i32.const 5)) -(assert_return (invoke "br_on_non_data" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_non_data" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_non_data" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_non_array" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_non_array" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_non_array" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_non_array" (i32.const 3)) (i32.const 3)) -(assert_return (invoke "br_on_non_array" (i32.const 4)) (i32.const -1)) -(assert_return (invoke "br_on_non_array" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_non_array" (i32.const 6)) (i32.const -1)) - -(assert_return (invoke "br_on_non_func" (i32.const 0)) (i32.const -1)) -(assert_return (invoke "br_on_non_func" (i32.const 1)) (i32.const -1)) -(assert_return (invoke "br_on_non_func" (i32.const 2)) (i32.const -1)) -(assert_return (invoke "br_on_non_func" (i32.const 3)) (i32.const -1)) -(assert_return (invoke "br_on_non_func" (i32.const 4)) (i32.const 9)) -(assert_return (invoke "br_on_non_func" (i32.const 5)) (i32.const -1)) -(assert_return (invoke "br_on_non_func" (i32.const 6)) (i32.const -1)) diff --git a/proposals/gc/br_on_non_null.wast b/proposals/gc/br_on_non_null.wast index 145b4f8..9c33bf6 100644 --- a/proposals/gc/br_on_non_null.wast +++ b/proposals/gc/br_on_non_null.wast @@ -2,7 +2,7 @@ (type $t (func (result i32))) (func $nn (param $r (ref $t)) (result i32) - (call_ref + (call_ref $t (block $l (result (ref $t)) (br_on_non_null $l (local.get $r)) (return (i32.const -1)) @@ -10,7 +10,7 @@ ) ) (func $n (param $r (ref null $t)) (result i32) - (call_ref + (call_ref $t (block $l (result (ref $t)) (br_on_non_null $l (local.get $r)) (return (i32.const -1)) @@ -26,10 +26,11 @@ (func (export "nullable-f") (result i32) (call $n (ref.func $f))) (func (export "unreachable") (result i32) - (block $l - (return (call_ref (br_on_null $l (unreachable)))) + (block $l (result (ref $t)) + (br_on_non_null $l (unreachable)) + (return (i32.const -1)) ) - (i32.const -1) + (call_ref $t) ) ) @@ -53,7 +54,7 @@ (func $f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0))) (func $a (param $n i32) (param $r (ref null $t)) (result i32) - (call_ref + (call_ref $t (block $l (result i32 (ref $t)) (return (br_on_non_null $l (local.get $n) (local.get $r))) ) diff --git a/proposals/gc/br_on_null.wast b/proposals/gc/br_on_null.wast index ec3471c..c6505a3 100644 --- a/proposals/gc/br_on_null.wast +++ b/proposals/gc/br_on_null.wast @@ -3,13 +3,13 @@ (func $nn (param $r (ref $t)) (result i32) (block $l - (return (call_ref (br_on_null $l (local.get $r)))) + (return (call_ref $t (br_on_null $l (local.get $r)))) ) (i32.const -1) ) (func $n (param $r (ref null $t)) (result i32) (block $l - (return (call_ref (br_on_null $l (local.get $r)))) + (return (call_ref $t (br_on_null $l (local.get $r)))) ) (i32.const -1) ) @@ -23,7 +23,7 @@ (func (export "unreachable") (result i32) (block $l - (return (call_ref (br_on_null $l (unreachable)))) + (return (call_ref $t (br_on_null $l (unreachable)))) ) (i32.const -1) ) @@ -50,7 +50,7 @@ (func $a (param $n i32) (param $r (ref null $t)) (result i32) (block $l (result i32) - (return (call_ref (br_on_null $l (local.get $n) (local.get $r)))) + (return (call_ref $t (br_on_null $l (local.get $n) (local.get $r)))) ) ) diff --git a/proposals/gc/call_ref.wast b/proposals/gc/call_ref.wast index 503c4e8..4253395 100644 --- a/proposals/gc/call_ref.wast +++ b/proposals/gc/call_ref.wast @@ -2,7 +2,7 @@ (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)) + (call_ref $ii (local.get $x) (local.get $f)) ) (func $f (type $ii) (i32.mul (local.get 0) (local.get 0))) @@ -15,11 +15,11 @@ (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)) + (call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg)) ) (func (export "null") (result i32) - (call_ref (i32.const 1) (ref.null $ii)) + (call_ref $ii (i32.const 1) (ref.null $ii)) ) ;; Recursion @@ -36,7 +36,7 @@ (else (i64.mul (local.get 0) - (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fac)) + (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac)) ) ) ) @@ -49,7 +49,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (local.get 1)) (else - (call_ref + (call_ref $lll (i64.sub (local.get 0) (i64.const 1)) (i64.mul (local.get 0) (local.get 1)) (global.get $fac-acc) @@ -66,8 +66,8 @@ (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)) + (call_ref $ll (i64.sub (local.get 0) (i64.const 2)) (global.get $fib)) + (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fib)) ) ) ) @@ -80,13 +80,13 @@ (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))) + (else (call_ref $ll (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))) + (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even))) ) ) ) @@ -127,34 +127,37 @@ ;; Unreachable typing. (module + (type $t (func)) (func (export "unreachable") (result i32) (unreachable) - (call_ref) + (call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (call_ref) + (call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i32.const 0) (ref.func $f) - (call_ref) + (call_ref $t) (drop) (i32.const 0) ) @@ -164,13 +167,14 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i64.const 0) (ref.func $f) - (call_ref) + (call_ref $t) ) ) "type mismatch" @@ -179,12 +183,13 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (call_ref) + (call_ref $t) (drop) (i64.const 0) ) @@ -194,8 +199,9 @@ (assert_invalid (module + (type $t (func)) (func $f (param $r externref) - (call_ref (local.get $r)) + (call_ref $t (local.get $r)) ) ) "type mismatch" diff --git a/proposals/gc/data.wast b/proposals/gc/data.wast new file mode 100644 index 0000000..a5c87fb --- /dev/null +++ b/proposals/gc/data.wast @@ -0,0 +1,492 @@ +;; Test the data section + +;; Syntax + +(module + (memory $m 1) + (data (i32.const 0)) + (data (i32.const 1) "a" "" "bcd") + (data (offset (i32.const 0))) + (data (offset (i32.const 0)) "" "a" "bc" "") + (data (memory 0) (i32.const 0)) + (data (memory 0x0) (i32.const 1) "a" "" "bcd") + (data (memory 0x000) (offset (i32.const 0))) + (data (memory 0) (offset (i32.const 0)) "" "a" "bc" "") + (data (memory $m) (i32.const 0)) + (data (memory $m) (i32.const 1) "a" "" "bcd") + (data (memory $m) (offset (i32.const 0))) + (data (memory $m) (offset (i32.const 0)) "" "a" "bc" "") + (data $d1 (i32.const 0)) + (data $d2 (i32.const 1) "a" "" "bcd") + (data $d3 (offset (i32.const 0))) + (data $d4 (offset (i32.const 0)) "" "a" "bc" "") + (data $d5 (memory 0) (i32.const 0)) + (data $d6 (memory 0x0) (i32.const 1) "a" "" "bcd") + (data $d7 (memory 0x000) (offset (i32.const 0))) + (data $d8 (memory 0) (offset (i32.const 0)) "" "a" "bc" "") + (data $d9 (memory $m) (i32.const 0)) + (data $d10 (memory $m) (i32.const 1) "a" "" "bcd") + (data $d11 (memory $m) (offset (i32.const 0))) + (data $d12 (memory $m) (offset (i32.const 0)) "" "a" "bc" "") +) + +;; Basic use + +(module + (memory 1) + (data (i32.const 0) "a") +) +(module + (import "spectest" "memory" (memory 1)) + (data (i32.const 0) "a") +) + +(module + (memory 1) + (data (i32.const 0) "a") + (data (i32.const 3) "b") + (data (i32.const 100) "cde") + (data (i32.const 5) "x") + (data (i32.const 3) "c") +) +(module + (import "spectest" "memory" (memory 1)) + (data (i32.const 0) "a") + (data (i32.const 1) "b") + (data (i32.const 2) "cde") + (data (i32.const 3) "f") + (data (i32.const 2) "g") + (data (i32.const 1) "h") +) + +(module + (global (import "spectest" "global_i32") i32) + (memory 1) + (data (global.get 0) "a") +) +(module + (global (import "spectest" "global_i32") i32) + (import "spectest" "memory" (memory 1)) + (data (global.get 0) "a") +) + +(module + (global $g (import "spectest" "global_i32") i32) + (memory 1) + (data (global.get $g) "a") +) +(module + (global $g (import "spectest" "global_i32") i32) + (import "spectest" "memory" (memory 1)) + (data (global.get $g) "a") +) + +(module (memory 1) (global i32 (i32.const 0)) (data (global.get 0) "a")) +(module (memory 1) (global $g i32 (i32.const 0)) (data (global.get $g) "a")) + + +;; Corner cases + +(module + (memory 1) + (data (i32.const 0) "a") + (data (i32.const 0xffff) "b") +) +(module + (import "spectest" "memory" (memory 1)) + (data (i32.const 0) "a") + (data (i32.const 0xffff) "b") +) + +(module + (memory 2) + (data (i32.const 0x1_ffff) "a") +) + +(module + (memory 0) + (data (i32.const 0)) +) +(module + (import "spectest" "memory" (memory 0)) + (data (i32.const 0)) +) + +(module + (memory 0 0) + (data (i32.const 0)) +) + +(module + (memory 1) + (data (i32.const 0x1_0000) "") +) + +(module + (memory 0) + (data (i32.const 0) "" "") +) +(module + (import "spectest" "memory" (memory 0)) + (data (i32.const 0) "" "") +) + +(module + (memory 0 0) + (data (i32.const 0) "" "") +) + +(module + (import "spectest" "memory" (memory 0)) + (data (i32.const 0) "a") +) + +(module + (import "spectest" "memory" (memory 0 3)) + (data (i32.const 0) "a") +) + +(module + (global (import "spectest" "global_i32") i32) + (import "spectest" "memory" (memory 0)) + (data (global.get 0) "a") +) + +(module + (global (import "spectest" "global_i32") i32) + (import "spectest" "memory" (memory 0 3)) + (data (global.get 0) "a") +) + +(module + (import "spectest" "memory" (memory 0)) + (data (i32.const 1) "a") +) + +(module + (import "spectest" "memory" (memory 0 3)) + (data (i32.const 1) "a") +) + +;; Invalid bounds for data + +(assert_trap + (module + (memory 0) + (data (i32.const 0) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 0 0) + (data (i32.const 0) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 0 1) + (data (i32.const 0) "a") + ) + "out of bounds memory access" +) +(assert_trap + (module + (memory 0) + (data (i32.const 1)) + ) + "out of bounds memory access" +) +(assert_trap + (module + (memory 0 1) + (data (i32.const 1)) + ) + "out of bounds memory access" +) + +;; This seems to cause a time-out on Travis. +(;assert_unlinkable + (module + (memory 0x10000) + (data (i32.const 0xffffffff) "ab") + ) + "" ;; either out of memory or out of bounds +;) + +(assert_trap + (module + (global (import "spectest" "global_i32") i32) + (memory 0) + (data (global.get 0) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 1 2) + (data (i32.const 0x1_0000) "a") + ) + "out of bounds memory access" +) +(assert_trap + (module + (import "spectest" "memory" (memory 1)) + (data (i32.const 0x1_0000) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 2) + (data (i32.const 0x2_0000) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 2 3) + (data (i32.const 0x2_0000) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 1) + (data (i32.const -1) "a") + ) + "out of bounds memory access" +) +(assert_trap + (module + (import "spectest" "memory" (memory 1)) + (data (i32.const -1) "a") + ) + "out of bounds memory access" +) + +(assert_trap + (module + (memory 2) + (data (i32.const -100) "a") + ) + "out of bounds memory access" +) +(assert_trap + (module + (import "spectest" "memory" (memory 1)) + (data (i32.const -100) "a") + ) + "out of bounds memory access" +) + +;; Data without memory + +(assert_invalid + (module + (data (i32.const 0) "") + ) + "unknown memory" +) + +;; Data segment with memory index 1 (only memory 0 available) +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; memory section + "\00\00" ;; memory 0 + "\0b\07\01" ;; data section + "\02\01\41\00\0b" ;; active data segment 0 for memory 1 + "\00" ;; empty vec(byte) + ) + "unknown memory 1" +) + +;; Data segment with memory index 0 (no memory section) +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\0b\06\01" ;; data section + "\00\41\00\0b" ;; active data segment 0 for memory 0 + "\00" ;; empty vec(byte) + ) + "unknown memory 0" +) + +;; Data segment with memory index 1 (no memory section) +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\0b\07\01" ;; data section + "\02\01\41\00\0b" ;; active data segment 0 for memory 1 + "\00" ;; empty vec(byte) + ) + "unknown memory 1" +) + +;; Data segment with memory index 1 and vec(byte) as above, +;; only memory 0 available. +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\05\03\01" ;; memory section + "\00\00" ;; memory 0 + "\0b\45\01" ;; data section + "\02" ;; active segment + "\01" ;; memory index + "\41\00\0b" ;; offset constant expression + "\3e" ;; vec(byte) length + "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f" + "\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f" + "\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f" + "\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d" + ) + "unknown memory 1" +) + +;; Data segment with memory index 1 and specially crafted vec(byte) after. +;; This is to detect incorrect validation where memory index is interpreted +;; as a flag followed by "\41" interpreted as the size of vec(byte) +;; with the expected number of bytes following. +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\0b\45\01" ;; data section + "\02" ;; active segment + "\01" ;; memory index + "\41\00\0b" ;; offset constant expression + "\3e" ;; vec(byte) length + "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f" + "\10\11\12\13\14\15\16\17\18\19\1a\1b\1c\1d\1e\1f" + "\20\21\22\23\24\25\26\27\28\29\2a\2b\2c\2d\2e\2f" + "\30\31\32\33\34\35\36\37\38\39\3a\3b\3c\3d" + ) + "unknown memory 1" +) + + +;; Invalid offsets + +(assert_invalid + (module + (memory 1) + (data (i64.const 0)) + ) + "type mismatch" +) + +(assert_invalid + (module + (memory 1) + (data (ref.null func)) + ) + "type mismatch" +) + +(assert_invalid + (module + (memory 1) + (data (offset (;empty instruction sequence;))) + ) + "type mismatch" +) + +(assert_invalid + (module + (memory 1) + (data (offset (i32.const 0) (i32.const 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (memory 1) + (data (offset (global.get 0) (global.get 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (memory 1) + (data (offset (global.get 0) (i32.const 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (memory 1) + (data (i32.ctz (i32.const 0))) + ) + "constant expression required" +) + +(assert_invalid + (module + (memory 1) + (data (nop)) + ) + "constant expression required" +) + +(assert_invalid + (module + (memory 1) + (data (offset (nop) (i32.const 0))) + ) + "constant expression required" +) + +(assert_invalid + (module + (memory 1) + (data (offset (i32.const 0) (nop))) + ) + "constant expression required" +) + +(assert_invalid + (module + (global $g (import "test" "g") (mut i32)) + (memory 1) + (data (global.get $g)) + ) + "constant expression required" +) + +(assert_invalid + (module + (memory 1) + (data (global.get 0)) + ) + "unknown global 0" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (memory 1) + (data (global.get 1)) + ) + "unknown global 1" +) + +(assert_invalid + (module + (global (import "test" "global-mut-i32") (mut i32)) + (memory 1) + (data (global.get 0)) + ) + "constant expression required" +) diff --git a/proposals/gc/elem.wast b/proposals/gc/elem.wast new file mode 100644 index 0000000..1eaa591 --- /dev/null +++ b/proposals/gc/elem.wast @@ -0,0 +1,658 @@ +;; Test the element section + +;; Syntax +(module + (table $t 10 funcref) + (func $f) + (func $g) + + ;; Passive + (elem funcref) + (elem funcref (ref.func $f) (item ref.func $f) (item (ref.null func)) (ref.func $g)) + (elem func) + (elem func $f $f $g $g) + + (elem $p1 funcref) + (elem $p2 funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g)) + (elem $p3 func) + (elem $p4 func $f $f $g $g) + + ;; Active + (elem (table $t) (i32.const 0) funcref) + (elem (table $t) (i32.const 0) funcref (ref.func $f) (ref.null func)) + (elem (table $t) (i32.const 0) func) + (elem (table $t) (i32.const 0) func $f $g) + (elem (table $t) (offset (i32.const 0)) funcref) + (elem (table $t) (offset (i32.const 0)) func $f $g) + (elem (table 0) (i32.const 0) func) + (elem (table 0x0) (i32.const 0) func $f $f) + (elem (table 0x000) (offset (i32.const 0)) func) + (elem (table 0) (offset (i32.const 0)) func $f $f) + (elem (table $t) (i32.const 0) func) + (elem (table $t) (i32.const 0) func $f $f) + (elem (table $t) (offset (i32.const 0)) func) + (elem (table $t) (offset (i32.const 0)) func $f $f) + (elem (offset (i32.const 0))) + (elem (offset (i32.const 0)) funcref (ref.func $f) (ref.null func)) + (elem (offset (i32.const 0)) func $f $f) + (elem (offset (i32.const 0)) $f $f) + (elem (i32.const 0)) + (elem (i32.const 0) funcref (ref.func $f) (ref.null func)) + (elem (i32.const 0) func $f $f) + (elem (i32.const 0) $f $f) + (elem (i32.const 0) funcref (item (ref.func $f)) (item (ref.null func))) + + (elem $a1 (table $t) (i32.const 0) funcref) + (elem $a2 (table $t) (i32.const 0) funcref (ref.func $f) (ref.null func)) + (elem $a3 (table $t) (i32.const 0) func) + (elem $a4 (table $t) (i32.const 0) func $f $g) + (elem $a9 (table $t) (offset (i32.const 0)) funcref) + (elem $a10 (table $t) (offset (i32.const 0)) func $f $g) + (elem $a11 (table 0) (i32.const 0) func) + (elem $a12 (table 0x0) (i32.const 0) func $f $f) + (elem $a13 (table 0x000) (offset (i32.const 0)) func) + (elem $a14 (table 0) (offset (i32.const 0)) func $f $f) + (elem $a15 (table $t) (i32.const 0) func) + (elem $a16 (table $t) (i32.const 0) func $f $f) + (elem $a17 (table $t) (offset (i32.const 0)) func) + (elem $a18 (table $t) (offset (i32.const 0)) func $f $f) + (elem $a19 (offset (i32.const 0))) + (elem $a20 (offset (i32.const 0)) funcref (ref.func $f) (ref.null func)) + (elem $a21 (offset (i32.const 0)) func $f $f) + (elem $a22 (offset (i32.const 0)) $f $f) + (elem $a23 (i32.const 0)) + (elem $a24 (i32.const 0) funcref (ref.func $f) (ref.null func)) + (elem $a25 (i32.const 0) func $f $f) + (elem $a26 (i32.const 0) $f $f) + + ;; Declarative + (elem declare funcref) + (elem declare funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g)) + (elem declare func) + (elem declare func $f $f $g $g) + + (elem $d1 declare funcref) + (elem $d2 declare funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g)) + (elem $d3 declare func) + (elem $d4 declare func $f $f $g $g) +) + +(module + (func $f) + (func $g) + + (table $t funcref (elem (ref.func $f) (ref.null func) (ref.func $g))) +) + + +;; Basic use + +(module + (table 10 funcref) + (func $f) + (elem (i32.const 0) $f) +) +(module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const 0) $f) +) + +(module + (table 10 funcref) + (func $f) + (elem (i32.const 0) $f) + (elem (i32.const 3) $f) + (elem (i32.const 7) $f) + (elem (i32.const 5) $f) + (elem (i32.const 3) $f) +) +(module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const 9) $f) + (elem (i32.const 3) $f) + (elem (i32.const 7) $f) + (elem (i32.const 3) $f) + (elem (i32.const 5) $f) +) + +(module + (global (import "spectest" "global_i32") i32) + (table 1000 funcref) + (func $f) + (elem (global.get 0) $f) +) + +(module + (global $g (import "spectest" "global_i32") i32) + (table 1000 funcref) + (func $f) + (elem (global.get $g) $f) +) + +(module + (type $out-i32 (func (result i32))) + (table 10 funcref) + (elem (i32.const 7) $const-i32-a) + (elem (i32.const 9) $const-i32-b) + (func $const-i32-a (type $out-i32) (i32.const 65)) + (func $const-i32-b (type $out-i32) (i32.const 66)) + (func (export "call-7") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 7)) + ) + (func (export "call-9") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 9)) + ) +) +(assert_return (invoke "call-7") (i32.const 65)) +(assert_return (invoke "call-9") (i32.const 66)) + +(module + (global i32 (i32.const 0)) + (table 1 funcref) (elem (global.get 0) $f) (func $f) +) +(module + (global $g i32 (i32.const 0)) + (table 1 funcref) (elem (global.get $g) $f) (func $f) +) + + +;; Corner cases + +(module + (table 10 funcref) + (func $f) + (elem (i32.const 9) $f) +) +(module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const 9) $f) +) + +(module + (table 0 funcref) + (elem (i32.const 0)) +) +(module + (import "spectest" "table" (table 0 funcref)) + (elem (i32.const 0)) +) + +(module + (table 0 0 funcref) + (elem (i32.const 0)) +) + +(module + (table 20 funcref) + (elem (i32.const 20)) +) + +(module + (import "spectest" "table" (table 0 funcref)) + (func $f) + (elem (i32.const 0) $f) +) + +(module + (import "spectest" "table" (table 0 100 funcref)) + (func $f) + (elem (i32.const 0) $f) +) + +(module + (import "spectest" "table" (table 0 funcref)) + (func $f) + (elem (i32.const 1) $f) +) + +(module + (import "spectest" "table" (table 0 30 funcref)) + (func $f) + (elem (i32.const 1) $f) +) + +;; Invalid bounds for elements + +(assert_trap + (module + (table 0 funcref) + (func $f) + (elem (i32.const 0) $f) + ) + "out of bounds table access" +) + +(assert_trap + (module + (table 0 0 funcref) + (func $f) + (elem (i32.const 0) $f) + ) + "out of bounds table access" +) + +(assert_trap + (module + (table 0 1 funcref) + (func $f) + (elem (i32.const 0) $f) + ) + "out of bounds table access" +) + +(assert_trap + (module + (table 0 funcref) + (elem (i32.const 1)) + ) + "out of bounds table access" +) +(assert_trap + (module + (table 10 funcref) + (func $f) + (elem (i32.const 10) $f) + ) + "out of bounds table access" +) +(assert_trap + (module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const 10) $f) + ) + "out of bounds table access" +) + +(assert_trap + (module + (table 10 20 funcref) + (func $f) + (elem (i32.const 10) $f) + ) + "out of bounds table access" +) +(assert_trap + (module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const 10) $f) + ) + "out of bounds table access" +) + +(assert_trap + (module + (table 10 funcref) + (func $f) + (elem (i32.const -1) $f) + ) + "out of bounds table access" +) +(assert_trap + (module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const -1) $f) + ) + "out of bounds table access" +) + +(assert_trap + (module + (table 10 funcref) + (func $f) + (elem (i32.const -10) $f) + ) + "out of bounds table access" +) +(assert_trap + (module + (import "spectest" "table" (table 10 funcref)) + (func $f) + (elem (i32.const -10) $f) + ) + "out of bounds table access" +) + +;; Implicitly dropped elements + +(module + (table 10 funcref) + (elem $e (i32.const 0) func $f) + (func $f) + (func (export "init") + (table.init $e (i32.const 0) (i32.const 0) (i32.const 1)) + ) +) +(assert_trap (invoke "init") "out of bounds table access") + +(module + (table 10 funcref) + (elem $e declare func $f) + (func $f) + (func (export "init") + (table.init $e (i32.const 0) (i32.const 0) (i32.const 1)) + ) +) +(assert_trap (invoke "init") "out of bounds table access") + +;; Element without table + +(assert_invalid + (module + (func $f) + (elem (i32.const 0) $f) + ) + "unknown table" +) + +;; Invalid offsets + +(assert_invalid + (module + (table 1 funcref) + (elem (i64.const 0)) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (ref.null func)) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (offset (;empty instruction sequence;))) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (offset (i32.const 0) (i32.const 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (table 1 funcref) + (elem (offset (global.get 0) (global.get 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (table 1 funcref) + (elem (offset (global.get 0) (i32.const 0))) + ) + "type mismatch" +) + + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.ctz (i32.const 0))) + ) + "constant expression required" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (nop)) + ) + "constant expression required" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (offset (nop) (i32.const 0))) + ) + "constant expression required" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (offset (i32.const 0) (nop))) + ) + "constant expression required" +) + +(assert_invalid + (module + (global $g (import "test" "g") (mut i32)) + (table 1 funcref) + (elem (global.get $g)) + ) + "constant expression required" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (global.get 0)) + ) + "unknown global 0" +) + +(assert_invalid + (module + (global (import "test" "global-i32") i32) + (table 1 funcref) + (elem (global.get 1)) + ) + "unknown global 1" +) + +(assert_invalid + (module + (global (import "test" "global-mut-i32") (mut i32)) + (table 1 funcref) + (elem (global.get 0)) + ) + "constant expression required" +) + +;; Invalid elements + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.const 0) funcref (ref.null extern)) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.const 0) funcref (item (ref.null func) (ref.null func))) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.const 0) funcref (i32.const 0)) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.const 0) funcref (item (i32.const 0))) + ) + "type mismatch" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.const 0) funcref (item (call $f))) + (func $f (result funcref) (ref.null func)) + ) + "constant expression required" +) + +(assert_invalid + (module + (table 1 funcref) + (elem (i32.const 0) funcref (item (i32.add (i32.const 0) (i32.const 1)))) + ) + "constant expression required" +) + +;; Two elements target the same slot + +(module + (type $out-i32 (func (result i32))) + (table 10 funcref) + (elem (i32.const 9) $const-i32-a) + (elem (i32.const 9) $const-i32-b) + (func $const-i32-a (type $out-i32) (i32.const 65)) + (func $const-i32-b (type $out-i32) (i32.const 66)) + (func (export "call-overwritten") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 9)) + ) +) +(assert_return (invoke "call-overwritten") (i32.const 66)) + +(module + (type $out-i32 (func (result i32))) + (import "spectest" "table" (table 10 funcref)) + (elem (i32.const 9) $const-i32-a) + (elem (i32.const 9) $const-i32-b) + (func $const-i32-a (type $out-i32) (i32.const 65)) + (func $const-i32-b (type $out-i32) (i32.const 66)) + (func (export "call-overwritten-element") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 9)) + ) +) +(assert_return (invoke "call-overwritten-element") (i32.const 66)) + +;; Element sections across multiple modules change the same table + +(module $module1 + (type $out-i32 (func (result i32))) + (table (export "shared-table") 10 funcref) + (elem (i32.const 8) $const-i32-a) + (elem (i32.const 9) $const-i32-b) + (func $const-i32-a (type $out-i32) (i32.const 65)) + (func $const-i32-b (type $out-i32) (i32.const 66)) + (func (export "call-7") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 7)) + ) + (func (export "call-8") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 8)) + ) + (func (export "call-9") (type $out-i32) + (call_indirect (type $out-i32) (i32.const 9)) + ) +) + +(register "module1" $module1) + +(assert_trap (invoke $module1 "call-7") "uninitialized element") +(assert_return (invoke $module1 "call-8") (i32.const 65)) +(assert_return (invoke $module1 "call-9") (i32.const 66)) + +(module $module2 + (type $out-i32 (func (result i32))) + (import "module1" "shared-table" (table 10 funcref)) + (elem (i32.const 7) $const-i32-c) + (elem (i32.const 8) $const-i32-d) + (func $const-i32-c (type $out-i32) (i32.const 67)) + (func $const-i32-d (type $out-i32) (i32.const 68)) +) + +(assert_return (invoke $module1 "call-7") (i32.const 67)) +(assert_return (invoke $module1 "call-8") (i32.const 68)) +(assert_return (invoke $module1 "call-9") (i32.const 66)) + +(module $module3 + (type $out-i32 (func (result i32))) + (import "module1" "shared-table" (table 10 funcref)) + (elem (i32.const 8) $const-i32-e) + (elem (i32.const 9) $const-i32-f) + (func $const-i32-e (type $out-i32) (i32.const 69)) + (func $const-i32-f (type $out-i32) (i32.const 70)) +) + +(assert_return (invoke $module1 "call-7") (i32.const 67)) +(assert_return (invoke $module1 "call-8") (i32.const 69)) +(assert_return (invoke $module1 "call-9") (i32.const 70)) + +;; Element segments must match element type of table + +(assert_invalid + (module (func $f) (table 1 externref) (elem (i32.const 0) $f)) + "type mismatch" +) + +(assert_invalid + (module (table 1 funcref) (elem (i32.const 0) externref (ref.null extern))) + "type mismatch" +) + +(assert_invalid + (module + (func $f) + (table $t 1 externref) + (elem $e funcref (ref.func $f)) + (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1)))) + "type mismatch" +) + +(assert_invalid + (module + (table $t 1 funcref) + (elem $e externref (ref.null extern)) + (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1)))) + "type mismatch" +) + +;; Initializing a table with an externref-type element segment + +(module $m + (table $t (export "table") 2 externref) + (func (export "get") (param $i i32) (result externref) + (table.get $t (local.get $i))) + (func (export "set") (param $i i32) (param $x externref) + (table.set $t (local.get $i) (local.get $x)))) + +(register "exporter" $m) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.null extern)) + +(assert_return (invoke $m "set" (i32.const 0) (ref.extern 42))) +(assert_return (invoke $m "set" (i32.const 1) (ref.extern 137))) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.extern 42)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137)) + +(module + (import "exporter" "table" (table $t 2 externref)) + (elem (i32.const 0) externref (ref.null extern))) + +(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern)) +(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137)) diff --git a/proposals/gc/extern.wast b/proposals/gc/extern.wast new file mode 100644 index 0000000..1f32a0a --- /dev/null +++ b/proposals/gc/extern.wast @@ -0,0 +1,54 @@ +(module + (type $ft (func)) + (type $st (struct)) + (type $at (array i8)) + + (table 10 anyref) + + (elem declare func $f) + (func $f) + + (func (export "init") (param $x externref) + (table.set (i32.const 0) (ref.null any)) + (table.set (i32.const 1) (i31.new (i32.const 7))) + (table.set (i32.const 2) (struct.new_canon_default $st)) + (table.set (i32.const 3) (array.new_canon_default $at (i32.const 0))) + (table.set (i32.const 4) (extern.internalize (local.get $x))) + ) + + (func (export "internalize") (param externref) (result anyref) + (extern.internalize (local.get 0)) + ) + (func (export "externalize") (param anyref) (result externref) + (extern.externalize (local.get 0)) + ) + + (func (export "externalize-i") (param i32) (result externref) + (extern.externalize (table.get (local.get 0))) + ) + (func (export "externalize-ii") (param i32) (result anyref) + (extern.internalize (extern.externalize (table.get (local.get 0)))) + ) +) + +(invoke "init" (ref.extern 0)) + +(assert_return (invoke "internalize" (ref.extern 1)) (ref.host 1)) +(assert_return (invoke "internalize" (ref.null extern)) (ref.null any)) + +(assert_return (invoke "externalize" (ref.host 2)) (ref.extern 2)) +(assert_return (invoke "externalize" (ref.null any)) (ref.null extern)) + +(assert_return (invoke "externalize-i" (i32.const 0)) (ref.null extern)) +(assert_return (invoke "externalize-i" (i32.const 1)) (ref.extern)) +(assert_return (invoke "externalize-i" (i32.const 2)) (ref.extern)) +(assert_return (invoke "externalize-i" (i32.const 3)) (ref.extern)) +(assert_return (invoke "externalize-i" (i32.const 4)) (ref.extern)) +(assert_return (invoke "externalize-i" (i32.const 5)) (ref.null extern)) + +(assert_return (invoke "externalize-ii" (i32.const 0)) (ref.null any)) +(assert_return (invoke "externalize-ii" (i32.const 1)) (ref.i31)) +(assert_return (invoke "externalize-ii" (i32.const 2)) (ref.struct)) +(assert_return (invoke "externalize-ii" (i32.const 3)) (ref.array)) +(assert_return (invoke "externalize-ii" (i32.const 4)) (ref.host 0)) +(assert_return (invoke "externalize-ii" (i32.const 5)) (ref.null any)) diff --git a/proposals/gc/func.wast b/proposals/gc/func.wast index a5e0ec7..f2d18cc 100644 --- a/proposals/gc/func.wast +++ b/proposals/gc/func.wast @@ -639,15 +639,6 @@ ) "unknown type" ) -(assert_invalid - (module - (type $t (func)) - (func $f (drop (let (result (ref $t)) (ref.func $g)))) - (func $g (type 4)) - (elem declare func $g) - ) - "unknown type" -) ;; Invalid typing of locals @@ -666,8 +657,11 @@ ) (assert_invalid - (module (type $t (func)) (func $type-local-no-default (local (ref $t)))) - "non-defaultable local type" + (module + (type $t (func)) + (func $type-local-uninitialized (local $x (ref $t)) (drop (local.get $x))) + ) + "uninitialized local" ) @@ -967,22 +961,28 @@ ;; Duplicate name errors -(assert_malformed (module quote - "(func $foo)" - "(func $foo)") - "duplicate func") -(assert_malformed (module quote - "(import \"\" \"\" (func $foo))" - "(func $foo)") - "duplicate func") -(assert_malformed (module quote - "(import \"\" \"\" (func $foo))" - "(import \"\" \"\" (func $foo))") - "duplicate func") - -(assert_malformed (module quote "(func (param $foo i32) (param $foo i32))") - "duplicate local") -(assert_malformed (module quote "(func (param $foo i32) (local $foo i32))") - "duplicate local") -(assert_malformed (module quote "(func (local $foo i32) (local $foo i32))") - "duplicate local") +(assert_malformed + (module quote "(func $foo)" "(func $foo)") + "duplicate func" +) +(assert_malformed + (module quote "(import \"\" \"\" (func $foo))" "(func $foo)") + "duplicate func" +) +(assert_malformed + (module quote "(import \"\" \"\" (func $foo))" "(import \"\" \"\" (func $foo))") + "duplicate func" +) + +(assert_malformed + (module quote "(func (param $foo i32) (param $foo i32))") + "duplicate local" +) +(assert_malformed + (module quote "(func (param $foo i32) (local $foo i32))") + "duplicate local" +) +(assert_malformed + (module quote "(func (local $foo i32) (local $foo i32))") + "duplicate local" +) diff --git a/proposals/gc/func_bind.wast b/proposals/gc/func_bind.wast deleted file mode 100644 index c33654b..0000000 --- a/proposals/gc/func_bind.wast +++ /dev/null @@ -1,522 +0,0 @@ -(module - (type $unop (func (param i32) (result i32))) - - (elem func $add) - (func $add (param i32 i32) (result i32) (i32.add (local.get 0) (local.get 1))) - - (func $mk-adder (param $i i32) (result (ref $unop)) - (func.bind (type $unop) (local.get $i) (ref.func $add)) - ) - - (global $f (mut (ref null $unop)) (ref.null $unop)) - - (func (export "make") (param $i i32) - (global.set $f (call $mk-adder (local.get $i))) - ) - - (func (export "call") (param $j i32) (result i32) - (call_ref (local.get $j) (global.get $f)) - ) - - (func (export "call2") (param $i i32) (param $j i32) (param $k i32) (result i32) - (call $mk-adder (local.get $k)) - (let (result i32) (local $f (ref $unop)) ;; binds $f to top of stack - (i32.mul - (call_ref (local.get $i) (local.get $f)) - (call_ref (local.get $j) (local.get $f)) - ) - ) - ) - - (func (export "null") (result i32) - (func.bind (type $unop) (i32.const 1) (ref.null $unop)) - (drop) - ) -) - -(assert_trap (invoke "call" (i32.const 0)) "null function") - -(assert_return (invoke "make" (i32.const 3))) -(assert_return (invoke "call" (i32.const 2)) (i32.const 5)) -(assert_return (invoke "call" (i32.const 10)) (i32.const 13)) - -(assert_return (invoke "make" (i32.const 0))) -(assert_return (invoke "call" (i32.const 10)) (i32.const 10)) - -(assert_return (invoke "make" (i32.const -3))) -(assert_return (invoke "call" (i32.const 10)) (i32.const 7)) - -(assert_return (invoke "call2" (i32.const 2) (i32.const 3) (i32.const 0)) (i32.const 6)) -(assert_return (invoke "call2" (i32.const 2) (i32.const 5) (i32.const 1)) (i32.const 18)) -(assert_return (invoke "call2" (i32.const 2) (i32.const 5) (i32.const 7)) (i32.const 108)) - -(assert_trap (invoke "null") "null function") - -(module - (elem declare func $p $f) - (func $p (import "spectest" "print_f64_f64") (param f64 f64)) - (func $f (param f64 f64 f64 f64) (result f64) - (f64.const 0) - (f64.add (f64.mul (local.get 0) (f64.const 1000))) - (f64.add (f64.mul (local.get 1) (f64.const 100))) - (f64.add (f64.mul (local.get 2) (f64.const 10))) - (f64.add (f64.mul (local.get 3) (f64.const 1))) - ) - - (type $p0 (func (param))) - (type $p1 (func (param f64))) - (type $p2 (func (param f64 f64))) - (type $f0 (func (param) (result f64))) - (type $f1 (func (param f64) (result f64))) - (type $f2 (func (param f64 f64) (result f64))) - (type $f3 (func (param f64 f64 f64) (result f64))) - (type $f4 (func (param f64 f64 f64 f64) (result f64))) - - (table $tp 30 funcref) - (table $tf 50 funcref) - - (func (export "call-p0") (param $i i32) - (call_indirect $tp (type $p0) (local.get $i)) - ) - (func (export "call-p1") (param $i i32) (param f64) - (call_indirect $tp (type $p1) (local.get 1) (local.get $i)) - ) - (func (export "call-p2") (param $i i32) (param f64 f64) - (call_indirect $tp (type $p2) (local.get 1) (local.get 2) (local.get $i)) - ) - - (func (export "call-f0") (param $i i32) (result f64) - (call_indirect $tf (type $f0) (local.get $i)) - ) - (func (export "call-f1") (param $i i32) (param f64) (result f64) - (call_indirect $tf (type $f1) (local.get 1) (local.get $i)) - ) - (func (export "call-f2") (param $i i32) (param f64 f64) (result f64) - (call_indirect $tf (type $f2) (local.get 1) (local.get 2) (local.get $i)) - ) - (func (export "call-f3") (param $i i32) (param f64 f64 f64) (result f64) - (call_indirect $tf (type $f3) (local.get 1) (local.get 2) (local.get 3) (local.get $i)) - ) - (func (export "call-f4") (param $i i32) (param f64 f64 f64 f64) (result f64) - (call_indirect $tf (type $f4) (local.get 1) (local.get 2) (local.get 3) (local.get 4) (local.get $i)) - ) - - (func (export "init") - ;; Host closures with arity 2 - (table.set $tp (i32.const 20) - (ref.func $p) - ) - (table.set $tp (i32.const 21) - (func.bind (type $p2) - (ref.func $p)) - ) - - ;; Host closures with arity 1 - (table.set $tp (i32.const 10) - (func.bind (type $p1) (f64.const 1) - (ref.func $p)) - ) - (table.set $tp (i32.const 11) - (func.bind (type $p1) (f64.const 1) - (func.bind (type $p2) - (ref.func $p))) - ) - (table.set $tp (i32.const 12) - (func.bind (type $p1) - (func.bind (type $p1) (f64.const 1) - (func.bind (type $p2) - (ref.func $p)))) - ) - - ;; Host closures with arity 0 - (table.set $tp (i32.const 00) - (func.bind (type $p0) (f64.const 1) (f64.const 2) - (ref.func $p)) - ) - (table.set $tp (i32.const 01) - (func.bind (type $p0) (f64.const 2) - (func.bind (type $p1) (f64.const 1) - (ref.func $p))) - ) - (table.set $tp (i32.const 02) - (func.bind (type $p0) - (func.bind (type $p0) (f64.const 2) - (func.bind (type $p1) - (func.bind (type $p1) (f64.const 1) - (func.bind (type $p2) - (func.bind (type $p2) - (ref.func $p))))))) - ) - - ;; Wasm closures with arity 4 - (table.set $tf (i32.const 40) - (ref.func $f) - ) - (table.set $tf (i32.const 41) - (func.bind (type $f4) - (ref.func $f)) - ) - - ;; Wasm closures with arity 3 - (table.set $tf (i32.const 30) - (func.bind (type $f3) (f64.const 1) - (ref.func $f)) - ) - (table.set $tf (i32.const 31) - (func.bind (type $f3) (f64.const 1) - (func.bind (type $f4) - (ref.func $f))) - ) - (table.set $tf (i32.const 32) - (func.bind (type $f3) - (func.bind (type $f3) (f64.const 1) - (func.bind (type $f4) - (ref.func $f)))) - ) - - ;; Wasm closures with arity 2 - (table.set $tf (i32.const 20) - (func.bind (type $f2) (f64.const 1) (f64.const 2) - (ref.func $f)) - ) - (table.set $tf (i32.const 21) - (func.bind (type $f2) (f64.const 2) - (func.bind (type $f3) (f64.const 1) - (ref.func $f))) - ) - (table.set $tf (i32.const 22) - (func.bind (type $f2) - (func.bind (type $f2) (f64.const 2) - (func.bind (type $f3) - (func.bind (type $f3) (f64.const 1) - (func.bind (type $f4) - (func.bind (type $f4) - (ref.func $f))))))) - ) - - ;; Wasm closures with arity 1 - (table.set $tf (i32.const 10) - (func.bind (type $f1) (f64.const 1) (f64.const 2) (f64.const 3) - (ref.func $f)) - ) - (table.set $tf (i32.const 11) - (func.bind (type $f1) (f64.const 2) (f64.const 3) - (func.bind (type $f3) (f64.const 1) - (ref.func $f))) - ) - (table.set $tf (i32.const 12) - (func.bind (type $f1) (f64.const 3) - (func.bind (type $f2) (f64.const 1) (f64.const 2) - (ref.func $f))) - ) - (table.set $tf (i32.const 13) - (func.bind (type $f1) (f64.const 3) - (func.bind (type $f2) (f64.const 2) - (func.bind (type $f3) (f64.const 1) - (ref.func $f)))) - ) - (table.set $tf (i32.const 14) - (func.bind (type $f1) - (func.bind (type $f1) - (func.bind (type $f1) (f64.const 3) - (func.bind (type $f2) - (func.bind (type $f2) - (func.bind (type $f2) (f64.const 2) - (func.bind (type $f3) - (func.bind (type $f3) - (func.bind (type $f3) (f64.const 1) - (func.bind (type $f4) - (func.bind (type $f4) - (ref.func $f)))))))))))) - ) - - ;; Wasm closures with arity 0 - (table.set $tf (i32.const 00) - (func.bind (type $f0) (f64.const 1) (f64.const 2) (f64.const 3) (f64.const 4) - (ref.func $f)) - ) - (table.set $tf (i32.const 01) - (func.bind (type $f0) (f64.const 2) (f64.const 3) (f64.const 4) - (func.bind (type $f3) (f64.const 1) - (ref.func $f))) - ) - (table.set $tf (i32.const 02) - (func.bind (type $f0) (f64.const 3) (f64.const 4) - (func.bind (type $f2) (f64.const 1) (f64.const 2) - (ref.func $f))) - ) - (table.set $tf (i32.const 03) - (func.bind (type $f0) (f64.const 4) - (func.bind (type $f1) (f64.const 1) (f64.const 2) (f64.const 3) - (ref.func $f))) - ) - (table.set $tf (i32.const 04) - (func.bind (type $f0) (f64.const 3) (f64.const 4) - (func.bind (type $f2) (f64.const 2) - (func.bind (type $f3) (f64.const 1) - (ref.func $f)))) - ) - (table.set $tf (i32.const 05) - (func.bind (type $f0) (f64.const 4) - (func.bind (type $f1) (f64.const 2) (f64.const 3) - (func.bind (type $f3) (f64.const 1) - (ref.func $f)))) - ) - (table.set $tf (i32.const 06) - (func.bind (type $f0) (f64.const 4) - (func.bind (type $f1) (f64.const 3) - (func.bind (type $f2) (f64.const 1) (f64.const 2) - (ref.func $f)))) - ) - (table.set $tf (i32.const 07) - (func.bind (type $f0) (f64.const 4) - (func.bind (type $f1) (f64.const 3) - (func.bind (type $f2) (f64.const 2) - (func.bind (type $f3) (f64.const 1) - (func.bind (type $f4) - (ref.func $f)))))) - ) - (table.set $tf (i32.const 08) - (func.bind (type $f0) - (func.bind (type $f0) - (func.bind (type $f0) (f64.const 4) - (func.bind (type $f1) - (func.bind (type $f1) - (func.bind (type $f1) (f64.const 2) (f64.const 3) - (func.bind (type $f3) - (func.bind (type $f3) - (func.bind (type $f3) (f64.const 1) - (func.bind (type $f4) - (func.bind (type $f4) - (ref.func $f)))))))))))) - ) - ) -) - -(invoke "init") - -(assert_return (invoke "call-p0" (i32.const 00))) -(assert_return (invoke "call-p0" (i32.const 01))) -(assert_return (invoke "call-p0" (i32.const 02))) -(assert_return (invoke "call-p1" (i32.const 10) (f64.const 2))) -(assert_return (invoke "call-p1" (i32.const 11) (f64.const 2))) -(assert_return (invoke "call-p1" (i32.const 12) (f64.const 2))) -(assert_return (invoke "call-p2" (i32.const 20) (f64.const 1) (f64.const 2))) -(assert_return (invoke "call-p2" (i32.const 21) (f64.const 1) (f64.const 2))) - -(assert_return (invoke "call-f0" (i32.const 00)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 01)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 02)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 03)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 04)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 05)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 06)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 07)) (f64.const 1234)) -(assert_return (invoke "call-f0" (i32.const 08)) (f64.const 1234)) -(assert_return (invoke "call-f1" (i32.const 10) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f1" (i32.const 11) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f1" (i32.const 12) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f1" (i32.const 13) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f1" (i32.const 14) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f2" (i32.const 20) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f2" (i32.const 21) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f2" (i32.const 22) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f3" (i32.const 30) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f3" (i32.const 31) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f3" (i32.const 32) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f4" (i32.const 40) (f64.const 1) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234)) -(assert_return (invoke "call-f4" (i32.const 41) (f64.const 1) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234)) - - -;; A bound's function type is its refined (possibly super) type -(module - (type $ii (func (param i32) (result i32))) - (type $fu (func (param i32 (ref $ii)) (result funcref))) - (type $fl (sub $fu (func (param i32 funcref) (result (ref null $ii))))) - - (elem declare func $sqr $f) - (func $sqr (param i32) (result i32) (i32.mul (local.get 0) (local.get 0))) - (func $f (type $fl) (ref.func $sqr)) - - (table $t 10 funcref) - - (func (export "run") (result i32) - (table.set $t (i32.const 0) (func.bind (type $fu) (ref.func $f))) - (call_ref (i32.const 2) - (call_indirect $t (type $fl) (i32.const 0) (ref.null $fl) (i32.const 0)) - ) - ) -) - -(assert_trap (invoke "run") "indirect call type mismatch") - -(module - (type $ii (func (param i32) (result i32))) - (type $fu' (func (param (ref $ii)) (result funcref))) - (type $fl' (sub $fu' (func (param funcref) (result (ref null $ii))))) - (type $fl (func (param i32 funcref) (result (ref null $ii)))) - - (elem declare func $sqr $f) - (func $sqr (param i32) (result i32) (i32.mul (local.get 0) (local.get 0))) - (func $f (type $fl) (ref.func $sqr)) - - (table $t 10 funcref) - - (func (export "run") (result i32) - (table.set $t (i32.const 0) (func.bind (type $fu') (i32.const 0) (ref.func $f))) - (call_ref (i32.const 3) - (call_indirect $t (type $fl') (ref.null $fl') (i32.const 0)) - ) - ) -) - - - - -(assert_trap (invoke "run") "indirect call type mismatch") - - -;; Null and unreachable typing. - -(module - (type $t (func)) - (func (export "null") (result (ref $t)) - (ref.null $t) - (func.bind) - ) -) -(assert_trap (invoke "null") "null function") - -(module - (type $t (func (param f32))) - (func (export "null") (result (ref $t)) - (ref.null $t) - (func.bind (type $t)) - ) -) -(assert_trap (invoke "null") "null function") - -(module - (type $t0 (func)) - (type $t1 (func (param i64))) - (func (export "null") (result (ref $t0)) - (i64.const 0) - (ref.null $t1) - (func.bind) - ) -) -(assert_trap (invoke "null") "null function") - -(module - (type $t0 (func)) - (type $t1 (func (param i64))) - (func (export "null") (result (ref $t0)) - (i64.const 0) - (ref.null $t1) - (func.bind (type $t0)) - ) -) -(assert_trap (invoke "null") "null function") - -(assert_invalid - (module - (type $t (func (result f32))) - (func (export "null") (result i32) - (ref.null $t) - (func.bind) - ) - ) - "type mismatch" -) - - -(module - (type $t (func (param f32))) - (func (export "unreachable") (result (ref $t)) - (unreachable) - (func.bind (type $t)) - ) -) -(assert_trap (invoke "unreachable") "unreachable") - -(module - (type $t (func (param f32) (result i32))) - (elem declare func $f) - (func $f (param i32 f32) (result i32) (local.get 0)) - - (func (export "unreachable") (result (ref $t)) - (unreachable) - (ref.func $f) - (func.bind (type $t)) - ) -) -(assert_trap (invoke "unreachable") "unreachable") - -(assert_invalid - (module - (type $t (func (param f32))) - (elem declare func $f) - (func $f (param i32 f32) (result i32) (local.get 0)) - - (func (export "unreachable") (result (ref $t)) - (unreachable) - (i64.const 0) - (ref.func $f) - (func.bind (type $t)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (elem declare func $f) - (func $f (param i32) (result i32) (local.get 0)) - - (func (export "unreachable") (result (ref $t)) - (unreachable) - (ref.func $f) - (func.bind (type $t)) - (drop) - (i64.const 0) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (func (export "null") (result i32) - (unreachable) - (func.bind) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func (param f32))) - (elem declare func $f) - (func $f (param i32 i32) (result i32) (local.get 0)) - - (func (export "unreachable") (result (ref $t)) - (unreachable) - (ref.func $f) - (func.bind (type $t)) - ) - ) - "type mismatch" -) - -(assert_invalid - (module - (type $t (func)) - (func $f (param $r externref) - (func.bind (type $t) (local.get $r)) - (drop) - ) - ) - "type mismatch" -) diff --git a/proposals/gc/global.wast b/proposals/gc/global.wast new file mode 100644 index 0000000..621de79 --- /dev/null +++ b/proposals/gc/global.wast @@ -0,0 +1,627 @@ +;; Test globals + +(module + (global (import "spectest" "global_i32") i32) + (global (import "spectest" "global_i64") i64) + + (global $a i32 (i32.const -2)) + (global (;3;) f32 (f32.const -3)) + (global (;4;) f64 (f64.const -4)) + (global $b i64 (i64.const -5)) + + (global $x (mut i32) (i32.const -12)) + (global (;7;) (mut f32) (f32.const -13)) + (global (;8;) (mut f64) (f64.const -14)) + (global $y (mut i64) (i64.const -15)) + + (global $z1 i32 (global.get 0)) + (global $z2 i64 (global.get 1)) + + (global $r externref (ref.null extern)) + (global $mr (mut externref) (ref.null extern)) + (global funcref (ref.null func)) + + (func (export "get-a") (result i32) (global.get $a)) + (func (export "get-b") (result i64) (global.get $b)) + (func (export "get-r") (result externref) (global.get $r)) + (func (export "get-mr") (result externref) (global.get $mr)) + (func (export "get-x") (result i32) (global.get $x)) + (func (export "get-y") (result i64) (global.get $y)) + (func (export "get-z1") (result i32) (global.get $z1)) + (func (export "get-z2") (result i64) (global.get $z2)) + (func (export "set-x") (param i32) (global.set $x (local.get 0))) + (func (export "set-y") (param i64) (global.set $y (local.get 0))) + (func (export "set-mr") (param externref) (global.set $mr (local.get 0))) + + (func (export "get-3") (result f32) (global.get 3)) + (func (export "get-4") (result f64) (global.get 4)) + (func (export "get-7") (result f32) (global.get 7)) + (func (export "get-8") (result f64) (global.get 8)) + (func (export "set-7") (param f32) (global.set 7 (local.get 0))) + (func (export "set-8") (param f64) (global.set 8 (local.get 0))) + + ;; As the argument of control constructs and instructions + + (memory 1) + + (func $dummy) + + (func (export "as-select-first") (result i32) + (select (global.get $x) (i32.const 2) (i32.const 3)) + ) + (func (export "as-select-mid") (result i32) + (select (i32.const 2) (global.get $x) (i32.const 3)) + ) + (func (export "as-select-last") (result i32) + (select (i32.const 2) (i32.const 3) (global.get $x)) + ) + + (func (export "as-loop-first") (result i32) + (loop (result i32) + (global.get $x) (call $dummy) (call $dummy) + ) + ) + (func (export "as-loop-mid") (result i32) + (loop (result i32) + (call $dummy) (global.get $x) (call $dummy) + ) + ) + (func (export "as-loop-last") (result i32) + (loop (result i32) + (call $dummy) (call $dummy) (global.get $x) + ) + ) + + (func (export "as-if-condition") (result i32) + (if (result i32) (global.get $x) + (then (call $dummy) (i32.const 2)) + (else (call $dummy) (i32.const 3)) + ) + ) + (func (export "as-if-then") (result i32) + (if (result i32) (i32.const 1) + (then (global.get $x)) (else (i32.const 2)) + ) + ) + (func (export "as-if-else") (result i32) + (if (result i32) (i32.const 0) + (then (i32.const 2)) (else (global.get $x)) + ) + ) + + (func (export "as-br_if-first") (result i32) + (block (result i32) + (br_if 0 (global.get $x) (i32.const 2)) + (return (i32.const 3)) + ) + ) + (func (export "as-br_if-last") (result i32) + (block (result i32) + (br_if 0 (i32.const 2) (global.get $x)) + (return (i32.const 3)) + ) + ) + + (func (export "as-br_table-first") (result i32) + (block (result i32) + (global.get $x) (i32.const 2) (br_table 0 0) + ) + ) + (func (export "as-br_table-last") (result i32) + (block (result i32) + (i32.const 2) (global.get $x) (br_table 0 0) + ) + ) + + (func $func (param i32 i32) (result i32) (local.get 0)) + (type $check (func (param i32 i32) (result i32))) + (table funcref (elem $func)) + (func (export "as-call_indirect-first") (result i32) + (block (result i32) + (call_indirect (type $check) + (global.get $x) (i32.const 2) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-mid") (result i32) + (block (result i32) + (call_indirect (type $check) + (i32.const 2) (global.get $x) (i32.const 0) + ) + ) + ) + (func (export "as-call_indirect-last") (result i32) + (block (result i32) + (call_indirect (type $check) + (i32.const 2) (i32.const 0) (global.get $x) + ) + ) + ) + + (func (export "as-store-first") + (global.get $x) (i32.const 1) (i32.store) + ) + (func (export "as-store-last") + (i32.const 0) (global.get $x) (i32.store) + ) + (func (export "as-load-operand") (result i32) + (i32.load (global.get $x)) + ) + (func (export "as-memory.grow-value") (result i32) + (memory.grow (global.get $x)) + ) + + (func $f (param i32) (result i32) (local.get 0)) + (func (export "as-call-value") (result i32) + (call $f (global.get $x)) + ) + + (func (export "as-return-value") (result i32) + (global.get $x) (return) + ) + (func (export "as-drop-operand") + (drop (global.get $x)) + ) + (func (export "as-br-value") (result i32) + (block (result i32) (br 0 (global.get $x))) + ) + + (func (export "as-local.set-value") (param i32) (result i32) + (local.set 0 (global.get $x)) + (local.get 0) + ) + (func (export "as-local.tee-value") (param i32) (result i32) + (local.tee 0 (global.get $x)) + ) + (func (export "as-global.set-value") (result i32) + (global.set $x (global.get $x)) + (global.get $x) + ) + + (func (export "as-unary-operand") (result i32) + (i32.eqz (global.get $x)) + ) + (func (export "as-binary-operand") (result i32) + (i32.mul + (global.get $x) (global.get $x) + ) + ) + (func (export "as-compare-operand") (result i32) + (i32.gt_u + (global.get 0) (i32.const 1) + ) + ) +) + +(assert_return (invoke "get-a") (i32.const -2)) +(assert_return (invoke "get-b") (i64.const -5)) +(assert_return (invoke "get-r") (ref.null extern)) +(assert_return (invoke "get-mr") (ref.null extern)) +(assert_return (invoke "get-x") (i32.const -12)) +(assert_return (invoke "get-y") (i64.const -15)) +(assert_return (invoke "get-z1") (i32.const 666)) +(assert_return (invoke "get-z2") (i64.const 666)) + +(assert_return (invoke "get-3") (f32.const -3)) +(assert_return (invoke "get-4") (f64.const -4)) +(assert_return (invoke "get-7") (f32.const -13)) +(assert_return (invoke "get-8") (f64.const -14)) + +(assert_return (invoke "set-x" (i32.const 6))) +(assert_return (invoke "set-y" (i64.const 7))) + +(assert_return (invoke "set-7" (f32.const 8))) +(assert_return (invoke "set-8" (f64.const 9))) + +(assert_return (invoke "get-x") (i32.const 6)) +(assert_return (invoke "get-y") (i64.const 7)) +(assert_return (invoke "get-7") (f32.const 8)) +(assert_return (invoke "get-8") (f64.const 9)) + +(assert_return (invoke "set-7" (f32.const 8))) +(assert_return (invoke "set-8" (f64.const 9))) +(assert_return (invoke "set-mr" (ref.extern 10))) + +(assert_return (invoke "get-x") (i32.const 6)) +(assert_return (invoke "get-y") (i64.const 7)) +(assert_return (invoke "get-7") (f32.const 8)) +(assert_return (invoke "get-8") (f64.const 9)) +(assert_return (invoke "get-mr") (ref.extern 10)) + +(assert_return (invoke "as-select-first") (i32.const 6)) +(assert_return (invoke "as-select-mid") (i32.const 2)) +(assert_return (invoke "as-select-last") (i32.const 2)) + +(assert_return (invoke "as-loop-first") (i32.const 6)) +(assert_return (invoke "as-loop-mid") (i32.const 6)) +(assert_return (invoke "as-loop-last") (i32.const 6)) + +(assert_return (invoke "as-if-condition") (i32.const 2)) +(assert_return (invoke "as-if-then") (i32.const 6)) +(assert_return (invoke "as-if-else") (i32.const 6)) + +(assert_return (invoke "as-br_if-first") (i32.const 6)) +(assert_return (invoke "as-br_if-last") (i32.const 2)) + +(assert_return (invoke "as-br_table-first") (i32.const 6)) +(assert_return (invoke "as-br_table-last") (i32.const 2)) + +(assert_return (invoke "as-call_indirect-first") (i32.const 6)) +(assert_return (invoke "as-call_indirect-mid") (i32.const 2)) +(assert_trap (invoke "as-call_indirect-last") "undefined element") + +(assert_return (invoke "as-store-first")) +(assert_return (invoke "as-store-last")) +(assert_return (invoke "as-load-operand") (i32.const 1)) +(assert_return (invoke "as-memory.grow-value") (i32.const 1)) + +(assert_return (invoke "as-call-value") (i32.const 6)) + +(assert_return (invoke "as-return-value") (i32.const 6)) +(assert_return (invoke "as-drop-operand")) +(assert_return (invoke "as-br-value") (i32.const 6)) + +(assert_return (invoke "as-local.set-value" (i32.const 1)) (i32.const 6)) +(assert_return (invoke "as-local.tee-value" (i32.const 1)) (i32.const 6)) +(assert_return (invoke "as-global.set-value") (i32.const 6)) + +(assert_return (invoke "as-unary-operand") (i32.const 0)) +(assert_return (invoke "as-binary-operand") (i32.const 36)) +(assert_return (invoke "as-compare-operand") (i32.const 1)) + +(assert_invalid + (module (global f32 (f32.const 0)) (func (global.set 0 (f32.const 1)))) + "immutable global" +) + +(assert_invalid + (module (import "spectest" "global_i32" (global i32)) (func (global.set 0 (i32.const 1)))) + "immutable global" +) + +;; mutable globals can be exported +(module (global (mut f32) (f32.const 0)) (export "a" (global 0))) +(module (global (export "a") (mut f32) (f32.const 0))) + +(assert_invalid + (module (global f32 (f32.neg (f32.const 0)))) + "constant expression required" +) + +(assert_invalid + (module (global f32 (local.get 0))) + "constant expression required" +) + +(assert_invalid + (module (global f32 (f32.neg (f32.const 1)))) + "constant expression required" +) + +(assert_invalid + (module (global i32 (i32.const 0) (nop))) + "constant expression required" +) + +(assert_invalid + (module (global i32 (i32.ctz (i32.const 0)))) + "constant expression required" +) + +(assert_invalid + (module (global i32 (nop))) + "constant expression required" +) + +(assert_invalid + (module (global i32 (f32.const 0))) + "type mismatch" +) + +(assert_invalid + (module (global i32 (i32.const 0) (i32.const 0))) + "type mismatch" +) + +(assert_invalid + (module (global i32 (;empty instruction sequence;))) + "type mismatch" +) + +(assert_invalid + (module (global (import "" "") externref) (global funcref (global.get 0))) + "type mismatch" +) + +(assert_invalid + (module (global (import "test" "global-i32") i32) (global i32 (global.get 0) (global.get 0))) + "type mismatch" +) + +(assert_invalid + (module (global (import "test" "global-i32") i32) (global i32 (i32.const 0) (global.get 0))) + "type mismatch" +) + +(assert_invalid + (module (global i32 (global.get 0))) + "unknown global" +) + +(module (global i32 (i32.const 0)) (global i32 (global.get 0))) +(module (global $g i32 (i32.const 0)) (global i32 (global.get $g))) + +(assert_invalid + (module (global i32 (global.get 1)) (global i32 (i32.const 0))) + "unknown global" +) + +(assert_invalid + (module (global (import "test" "global-i32") i32) (global i32 (global.get 2))) + "unknown global" +) + +(assert_invalid + (module (global (import "test" "global-mut-i32") (mut i32)) (global i32 (global.get 0))) + "constant expression required" +) + +(module + (import "spectest" "global_i32" (global i32)) +) +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\02\98\80\80\80\00" ;; import section + "\01" ;; length 1 + "\08\73\70\65\63\74\65\73\74" ;; "spectest" + "\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\02" ;; malformed mutability + ) + "malformed mutability" +) +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\02\98\80\80\80\00" ;; import section + "\01" ;; length 1 + "\08\73\70\65\63\74\65\73\74" ;; "spectest" + "\0a\67\6c\6f\62\61\6c\5f\69\33\32" ;; "global_i32" + "\03" ;; GlobalImport + "\7f" ;; i32 + "\ff" ;; malformed mutability + ) + "malformed mutability" +) + +(module + (global i32 (i32.const 0)) +) +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\06\86\80\80\80\00" ;; global section + "\01" ;; length 1 + "\7f" ;; i32 + "\02" ;; malformed mutability + "\41\00" ;; i32.const 0 + "\0b" ;; end + ) + "malformed mutability" +) +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\06\86\80\80\80\00" ;; global section + "\01" ;; length 1 + "\7f" ;; i32 + "\ff" ;; malformed mutability + "\41\00" ;; i32.const 0 + "\0b" ;; end + ) + "malformed mutability" +) + +;; global.get with invalid index +(assert_invalid + (module (func (result i32) (global.get 0))) + "unknown global" +) + +(assert_invalid + (module + (global i32 (i32.const 0)) + (func (result i32) (global.get 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (func (result i32) (global.get 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (global i32 (i32.const 0)) + (func (result i32) (global.get 2)) + ) + "unknown global" +) + +;; global.set with invalid index +(assert_invalid + (module (func (i32.const 0) (global.set 0))) + "unknown global" +) + +(assert_invalid + (module + (global i32 (i32.const 0)) + (func (i32.const 0) (global.set 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (func (i32.const 0) (global.set 1)) + ) + "unknown global" +) + +(assert_invalid + (module + (import "spectest" "global_i32" (global i32)) + (global i32 (i32.const 0)) + (func (i32.const 0) (global.set 2)) + ) + "unknown global" +) + + +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty + (global.set $x) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-block + (i32.const 0) + (block (global.set $x)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-loop + (i32.const 0) + (loop (global.set $x)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-then + (i32.const 0) (i32.const 0) + (if (then (global.set $x))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-else + (i32.const 0) (i32.const 0) + (if (result i32) (then (i32.const 0)) (else (global.set $x))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-br + (i32.const 0) + (block (br 0 (global.set $x))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-br_if + (i32.const 0) + (block (br_if 0 (global.set $x))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-br_table + (i32.const 0) + (block (br_table 0 (global.set $x))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-return + (return (global.set $x)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-select + (select (global.set $x) (i32.const 1) (i32.const 2)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $type-global.set-value-empty-in-call + (call 1 (global.set $x)) + ) + (func (param i32) (result i32) (local.get 0)) + ) + "type mismatch" +) +(assert_invalid + (module + (global $x (mut i32) (i32.const 0)) + (func $f (param i32) (result i32) (local.get 0)) + (type $sig (func (param i32) (result i32))) + (table funcref (elem $f)) + (func $type-global.set-value-empty-in-call_indirect + (block (result i32) + (call_indirect (type $sig) + (global.set $x) (i32.const 0) + ) + ) + ) + ) + "type mismatch" +) + +;; Duplicate identifier errors + +(assert_malformed (module quote + "(global $foo i32 (i32.const 0))" + "(global $foo i32 (i32.const 0))") + "duplicate global") +(assert_malformed (module quote + "(import \"\" \"\" (global $foo i32))" + "(global $foo i32 (i32.const 0))") + "duplicate global") +(assert_malformed (module quote + "(import \"\" \"\" (global $foo i32))" + "(import \"\" \"\" (global $foo i32))") + "duplicate global") diff --git a/proposals/gc/i31.wast b/proposals/gc/i31.wast index 484d5a7..284b5d2 100644 --- a/proposals/gc/i31.wast +++ b/proposals/gc/i31.wast @@ -10,6 +10,13 @@ (i31.get_s (i31.new (local.get $i))) ) + (func (export "get_u-null") (result i32) + (i31.get_u (ref.null i31)) + ) + (func (export "get_s-null") (result i32) + (i31.get_u (ref.null i31)) + ) + (global $i (ref i31) (i31.new (i32.const 2))) (global $m (mut (ref i31)) (i31.new (i32.const 3))) (func (export "get_globals") (result i32 i32) @@ -38,4 +45,7 @@ (assert_return (invoke "get_s" (i32.const 0xaaaa_aaaa)) (i32.const 0x2aaa_aaaa)) (assert_return (invoke "get_s" (i32.const 0xcaaa_aaaa)) (i32.const 0xcaaa_aaaa)) +(assert_trap (invoke "get_u-null") "null i31 reference") +(assert_trap (invoke "get_s-null") "null i31 reference") + (assert_return (invoke "get_globals") (i32.const 2) (i32.const 3)) diff --git a/proposals/gc/let.wast b/proposals/gc/let.wast deleted file mode 100644 index 451bc5d..0000000 --- a/proposals/gc/let.wast +++ /dev/null @@ -1,302 +0,0 @@ -(module - ;; Auxiliary - (type $dummy (func)) - (elem declare func $dummy) - (func $dummy) - (func $consume (param i32)) - (func $produce (result i32) (i32.const 7)) - - (func (export "syntax") (param $x1 i32) (param $x2 i64) - (local $y1 i64) - (local $y2 i32) - (local.set $y2 (i32.const 5)) - - (let) - (let $l) - (let (local)) - (let $l (local)) - - (let (result) (local)) - (let $l (result) (local)) - - (let (call $dummy) (call $consume (local.get $x1))) - (let $l (call $dummy) (call $consume (local.get $y2))) - (let (local) (call $dummy) (call $consume (local.get $y2))) - (let $l (local) (call $dummy) (call $consume (local.get $x1))) - - (let (call $dummy) (call $dummy) (br 0)) - (let $l (call $dummy) (call $dummy) (br $l)) - (let (local) (call $dummy) (call $dummy) (br 0)) - (let $l (local) (call $dummy) (call $dummy) (br $l)) - - (i32.const 1) - (f32.const 2) - (let $l (param i32) (result i64) (local f32) (br $l (i64.const 3))) - (drop) - - (let (result i32) (call $dummy) (call $produce) (call $dummy)) - (drop) - (let $l (result i32) (call $dummy) (call $produce) (call $dummy)) - (drop) - (let (result i32) (local) (call $dummy) (call $produce) (call $dummy)) - (drop) - (let $l (result i32) (local) (call $dummy) (call $produce) (call $dummy)) - (drop) - - (i32.const 1) - (let (local i32) (call $dummy) (call $consume (local.get 0))) - (i32.const 2) - (let $l (local i32) (call $dummy) (call $consume (local.get 0))) - (i32.const 3) - (let (local i32) (call $dummy) (call $consume (local.get 0))) - (i32.const 4) - (let $l (local i32) (call $dummy) (call $consume (local.get 0))) - - (i32.const 1) (f32.const 2) (i32.const 3) (i64.const 4) - (let (local i32 f32) (local) (local $z i32) (local i64) - (call $consume (local.get 0)) - (call $consume (local.get 2)) ;; $z - (call $consume (local.get 4)) ;; $x1 - (call $consume (local.get 7)) ;; $y2 - (call $consume (local.get $z)) - (call $consume (local.get $x1)) - (call $consume (local.get $y2)) - ) - - (f32.const 1) (i32.const 2) (i64.const 3) (i32.const 4) - (let (result i32) (local $z1 f32) (local $z2 i32) (local) (local i64 i32) - (call $produce) - (call $consume (local.get 1)) ;; $z2 - (call $consume (local.get 3)) - (call $consume (local.get 4)) ;; $x1 - (call $consume (local.get 7)) ;; $y2 - (call $consume (local.get $z2)) - (call $consume (local.get $x1)) - (call $consume (local.get $y2)) - ) - (drop) - - (ref.func $dummy) - (let (local (ref $dummy))) - ) - - (func $pow (export "pow") (param $x i64) (param $n i32) (result i64) - (local $y i64) - (local.set $y - (if (result i64) (i32.and (local.get $n) (i32.const 1)) - (then (local.get $x)) (else (i64.const 1)) - ) - ) - (i64.mul - (local.get $y) - (if (result i64) (i32.le_u (local.get $n) (i32.const 1)) - (then (i64.const 1)) - (else - (call $pow - (i64.mul (local.get $x) (local.get $x)) - (i32.shr_u (local.get $n) (i32.const 1)) - ) - ) - ) - ) - ) - - (func (export "semantics-idx") (param i64 i64) (result i64) - (local i64 i64) - (local.set 2 (i64.const 5)) - (local.set 3 (i64.const 7)) - - (i64.const 11) (i64.const 13) - (let (result i64) (local i64 i64) - (i64.const 17) (i64.const 19) - (let (result i64) (local i64 i64) - (i64.const 0) - (i64.add (call $pow (local.get 0) (i32.const 0))) ;; 17^0 = 1 - (i64.add (call $pow (local.get 1) (i32.const 1))) ;; 19^1 = 19 - (i64.add (call $pow (local.get 2) (i32.const 2))) ;; 11^2 = 121 - (i64.add (call $pow (local.get 3) (i32.const 3))) ;; 13^3 = 2197 - (i64.add (call $pow (local.get 4) (i32.const 4))) ;; 2^4 = 16 - (i64.add (call $pow (local.get 5) (i32.const 5))) ;; 3^5 = 243 - (i64.add (call $pow (local.get 6) (i32.const 6))) ;; 5^6 = 15625 - (i64.add (call $pow (local.get 7) (i32.const 7))) ;; 7^7 = 823543 - ) - ) - ) - - (func (export "semantics-sym") (param $x1 i64) (param $x2 i64) (result i64) - (local $y1 i64) - (local $y2 i64) - (local.set $y1 (i64.const 5)) - (local.set $y2 (i64.const 7)) - - (i64.const 11) (i64.const 13) - (let (result i64) (local $z1 i64) (local $z2 i64) - (i64.const 17) (i64.const 19) - (let (result i64) (local $u1 i64) (local $u2 i64) - (i64.const 0) - (i64.add (call $pow (local.get $u1) (i32.const 0))) ;; 17^0 = 1 - (i64.add (call $pow (local.get $u2) (i32.const 1))) ;; 19^1 = 19 - (i64.add (call $pow (local.get $z1) (i32.const 2))) ;; 11^2 = 121 - (i64.add (call $pow (local.get $z2) (i32.const 3))) ;; 13^3 = 2197 - (i64.add (call $pow (local.get $x1) (i32.const 4))) ;; 2^4 = 16 - (i64.add (call $pow (local.get $x2) (i32.const 5))) ;; 3^5 = 243 - (i64.add (call $pow (local.get $y1) (i32.const 6))) ;; 5^6 = 15625 - (i64.add (call $pow (local.get $y2) (i32.const 7))) ;; 7^7 = 823543 - ) - ) - ) - - (func (export "mutate") (param $x1 i64) (param $x2 i64) (result i64) - (local $y1 i64) - (local $y2 i64) - - (i64.const 0) (i64.const 0) - (let (result i64) (local $z1 i64) (local $z2 i64) - (i64.const 0) (i64.const 0) - (let (result i64) (local $u1 i64) (local $u2 i64) - (local.set $y1 (i64.const 5)) - (local.set $y2 (i64.const 7)) - (local.set $z1 (i64.const 11)) - (local.set $z2 (i64.const 13)) - (local.set $u1 (i64.const 17)) - (local.set $u2 (i64.const 19)) - (i64.const 0) - (i64.add (call $pow (local.get $u1) (i32.const 0))) ;; 17^0 = 1 - (i64.add (call $pow (local.get $u2) (i32.const 1))) ;; 19^1 = 19 - (i64.add (call $pow (local.get $z1) (i32.const 2))) ;; 11^2 = 121 - (i64.add (call $pow (local.get $z2) (i32.const 3))) ;; 13^3 = 2197 - (i64.add (call $pow (local.get $x1) (i32.const 4))) ;; 2^4 = 16 - (i64.add (call $pow (local.get $x2) (i32.const 5))) ;; 3^5 = 243 - (i64.add (call $pow (local.get $y1) (i32.const 6))) ;; 5^6 = 15625 - (i64.add (call $pow (local.get $y2) (i32.const 7))) ;; 7^7 = 823543 - ) - ) - ) -) - -(assert_return (invoke "syntax" (i32.const 1) (i64.const 2))) - -(assert_return (invoke "pow" (i64.const 17) (i32.const 0)) (i64.const 1)) -(assert_return (invoke "pow" (i64.const 19) (i32.const 1)) (i64.const 19)) -(assert_return (invoke "pow" (i64.const 11) (i32.const 2)) (i64.const 121)) -(assert_return (invoke "pow" (i64.const 13) (i32.const 3)) (i64.const 2197)) -(assert_return (invoke "pow" (i64.const 2) (i32.const 4)) (i64.const 16)) -(assert_return (invoke "pow" (i64.const 3) (i32.const 5)) (i64.const 243)) -(assert_return (invoke "pow" (i64.const 5) (i32.const 6)) (i64.const 15625)) -(assert_return (invoke "pow" (i64.const 7) (i32.const 7)) (i64.const 823543)) - -(assert_return (invoke "semantics-idx" (i64.const 2) (i64.const 3)) (i64.const 841_765)) -(assert_return (invoke "semantics-sym" (i64.const 2) (i64.const 3)) (i64.const 841_765)) -(assert_return (invoke "mutate" (i64.const 2) (i64.const 3)) (i64.const 841_765)) - - -;; Shadowing. - -;; Shadowing is fine across nested let blocks (analogous to labels). -(module - (func (export "f1") (param $x i32) (result i32) - (i32.const 1) - (let (local $x i32) (return (local.get $x))) - (unreachable) - ) - (func (export "f2") (result i32) - (local $x i32) - (i32.const 1) - (let (local $x i32) (return (local.get $x))) - (unreachable) - ) - (func (export "f3") (result i32) - (i32.const 0) - (let (local $x i32) - (i32.const 1) - (let (local $x i32) (return (local.get $x))) - ) - (unreachable) - ) - (func (export "f4") (result i32) - (local $x i32) - (i32.const 1) - (let (local $x i32) - (i32.const 2) - (let (local $x i32) (return (local.get $x))) - ) - (unreachable) - ) -) - -(assert_return (invoke "f1" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "f2") (i32.const 1)) -(assert_return (invoke "f3") (i32.const 1)) -(assert_return (invoke "f4") (i32.const 2)) - -;; Duplicate labels within a single let block are still disallowed. -(assert_malformed - (module quote "(func (let (local $x i32) (local $x i64)))") - "duplicate local" -) - - -;; Syntax - -(assert_malformed - (module quote "(func (let (local) (param)))") - "unexpected token" -) -(assert_malformed - (module quote - "(func" - " (i32.const 0) (i32.const 0)" - " (let (local i32) (param i32) (drop))" - ")" - ) - "unexpected token" -) - -(assert_malformed - (module quote "(func (let (local) (result)))") - "unexpected token" -) -(assert_malformed - (module quote - "(func (result i32)" - " (i32.const 0)" - " (let (local i32) (result i32) (local.get 0))" - ")" - ) - "unexpected token" -) -(assert_malformed - (module quote - "(func (result i32)" - " (let (local $x i32) (result i32) (local.get 0))" - ")" - ) - "unexpected token" -) - -(assert_malformed - (module quote "(func (let (result) (param)))") - "unexpected token" -) -(assert_malformed - (module quote - "(func (result i32)" - " (i32.const 0)" - " (let (result i32) (param i32))" - ")" - ) - "unexpected token" -) - -(assert_malformed - (module quote "(func (let (param) $l))") - "unexpected token" -) -(assert_malformed - (module quote "(func (let (result) $l))") - "unexpected token" -) -(assert_malformed - (module quote "(func (let (local) $l))") - "unexpected token" -) diff --git a/proposals/gc/local_get.wast b/proposals/gc/local_get.wast new file mode 100644 index 0000000..b56aeec --- /dev/null +++ b/proposals/gc/local_get.wast @@ -0,0 +1,265 @@ +;; Test `local.get` operator + +(module + ;; Typing + + (func (export "type-local-i32") (result i32) (local i32) (local.get 0)) + (func (export "type-local-i64") (result i64) (local i64) (local.get 0)) + (func (export "type-local-f32") (result f32) (local f32) (local.get 0)) + (func (export "type-local-f64") (result f64) (local f64) (local.get 0)) + + (func (export "type-param-i32") (param i32) (result i32) (local.get 0)) + (func (export "type-param-i64") (param i64) (result i64) (local.get 0)) + (func (export "type-param-f32") (param f32) (result f32) (local.get 0)) + (func (export "type-param-f64") (param f64) (result f64) (local.get 0)) + + (func (export "type-mixed") (param i64 f32 f64 i32 i32) + (local f32 i64 i64 f64) + (drop (i64.eqz (local.get 0))) + (drop (f32.neg (local.get 1))) + (drop (f64.neg (local.get 2))) + (drop (i32.eqz (local.get 3))) + (drop (i32.eqz (local.get 4))) + (drop (f32.neg (local.get 5))) + (drop (i64.eqz (local.get 6))) + (drop (i64.eqz (local.get 7))) + (drop (f64.neg (local.get 8))) + ) + + ;; Reading + + (func (export "read") (param i64 f32 f64 i32 i32) (result f64) + (local f32 i64 i64 f64) + (local.set 5 (f32.const 5.5)) + (local.set 6 (i64.const 6)) + (local.set 8 (f64.const 8)) + (f64.add + (f64.convert_i64_u (local.get 0)) + (f64.add + (f64.promote_f32 (local.get 1)) + (f64.add + (local.get 2) + (f64.add + (f64.convert_i32_u (local.get 3)) + (f64.add + (f64.convert_i32_s (local.get 4)) + (f64.add + (f64.promote_f32 (local.get 5)) + (f64.add + (f64.convert_i64_u (local.get 6)) + (f64.add + (f64.convert_i64_u (local.get 7)) + (local.get 8) + ) + ) + ) + ) + ) + ) + ) + ) + ) + + ;; As parameter of control constructs and instructions + + (func (export "as-block-value") (param i32) (result i32) + (block (result i32) (local.get 0)) + ) + (func (export "as-loop-value") (param i32) (result i32) + (loop (result i32) (local.get 0)) + ) + (func (export "as-br-value") (param i32) (result i32) + (block (result i32) (br 0 (local.get 0))) + ) + (func (export "as-br_if-value") (param i32) (result i32) + (block $l0 (result i32) (br_if $l0 (local.get 0) (i32.const 1))) + ) + + (func (export "as-br_if-value-cond") (param i32) (result i32) + (block (result i32) + (br_if 0 (local.get 0) (local.get 0)) + ) + ) + (func (export "as-br_table-value") (param i32) (result i32) + (block + (block + (block + (br_table 0 1 2 (local.get 0)) + (return (i32.const 0)) + ) + (return (i32.const 1)) + ) + (return (i32.const 2)) + ) + (i32.const 3) + ) + + (func (export "as-return-value") (param i32) (result i32) + (return (local.get 0)) + ) + + (func (export "as-if-then") (param i32) (result i32) + (if (result i32) (local.get 0) (then (local.get 0)) (else (i32.const 0))) + ) + (func (export "as-if-else") (param i32) (result i32) + (if (result i32) (local.get 0) (then (i32.const 1)) (else (local.get 0))) + ) +) + +(assert_return (invoke "type-local-i32") (i32.const 0)) +(assert_return (invoke "type-local-i64") (i64.const 0)) +(assert_return (invoke "type-local-f32") (f32.const 0)) +(assert_return (invoke "type-local-f64") (f64.const 0)) + +(assert_return (invoke "type-param-i32" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "type-param-i64" (i64.const 3)) (i64.const 3)) +(assert_return (invoke "type-param-f32" (f32.const 4.4)) (f32.const 4.4)) +(assert_return (invoke "type-param-f64" (f64.const 5.5)) (f64.const 5.5)) + +(assert_return (invoke "as-block-value" (i32.const 6)) (i32.const 6)) +(assert_return (invoke "as-loop-value" (i32.const 7)) (i32.const 7)) + +(assert_return (invoke "as-br-value" (i32.const 8)) (i32.const 8)) +(assert_return (invoke "as-br_if-value" (i32.const 9)) (i32.const 9)) +(assert_return (invoke "as-br_if-value-cond" (i32.const 10)) (i32.const 10)) +(assert_return (invoke "as-br_table-value" (i32.const 1)) (i32.const 2)) + +(assert_return (invoke "as-return-value" (i32.const 0)) (i32.const 0)) + +(assert_return (invoke "as-if-then" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "as-if-else" (i32.const 0)) (i32.const 0)) + +(assert_return + (invoke "type-mixed" + (i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5) + ) +) + +(assert_return + (invoke "read" + (i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5) + ) + (f64.const 34.8) +) + + +;; Invalid typing of access to locals + +(assert_invalid + (module (func $type-local-num-vs-num (result i64) (local i32) (local.get 0))) + "type mismatch" +) +(assert_invalid + (module (func $type-local-num-vs-num (result i32) (local f32) (i32.eqz (local.get 0)))) + "type mismatch" +) +(assert_invalid + (module (func $type-local-num-vs-num (result f64) (local f64 i64) (f64.neg (local.get 1)))) + "type mismatch" +) + + +;; Invalid typing of access to parameters + +(assert_invalid + (module (func $type-param-num-vs-num (param i32) (result i64) (local.get 0))) + "type mismatch" +) +(assert_invalid + (module (func $type-param-num-vs-num (param f32) (result i32) (i32.eqz (local.get 0)))) + "type mismatch" +) +(assert_invalid + (module (func $type-param-num-vs-num (param f64 i64) (result f64) (f64.neg (local.get 1)))) + "type mismatch" +) + + +;; Invalid result type + +(assert_invalid + (module (func $type-empty-vs-i32 (local i32) (local.get 0))) + "type mismatch" +) +(assert_invalid + (module (func $type-empty-vs-i64 (local i64) (local.get 0))) + "type mismatch" +) +(assert_invalid + (module (func $type-empty-vs-f32 (local f32) (local.get 0))) + "type mismatch" +) +(assert_invalid + (module (func $type-empty-vs-f64 (local f64) (local.get 0))) + "type mismatch" +) + + +;; Invalid local index + +(assert_invalid + (module (func $unbound-local (local i32 i64) (local.get 3) drop)) + "unknown local" +) +(assert_invalid + (module (func $large-local (local i32 i64) (local.get 14324343) drop)) + "unknown local" +) + +(assert_invalid + (module (func $unbound-param (param i32 i64) (local.get 2) drop)) + "unknown local" +) +(assert_invalid + (module (func $large-param (param i32 i64) (local.get 714324343) drop)) + "unknown local" +) + +(assert_invalid + (module (func $unbound-mixed (param i32) (local i32 i64) (local.get 3) drop)) + "unknown local" +) +(assert_invalid + (module (func $large-mixed (param i64) (local i32 i64) (local.get 214324343) drop)) + "unknown local" +) + + +;; Uninitialized undefaulted locals + +(module + (func (export "get-after-set") (param $p (ref extern)) (result (ref extern)) + (local $x (ref extern)) + (local.set $x (local.get $p)) + (local.get $x) + ) + (func (export "get-after-tee") (param $p (ref extern)) (result (ref extern)) + (local $x (ref extern)) + (drop (local.tee $x (local.get $p))) + (local.get $x) + ) + (func (export "get-in-block-after-set") (param $p (ref extern)) (result (ref extern)) + (local $x (ref extern)) + (local.set $x (local.get $p)) + (block (result (ref extern)) (local.get $x)) + ) +) + +(assert_return (invoke "get-after-set" (ref.extern 1)) (ref.extern 1)) +(assert_return (invoke "get-after-tee" (ref.extern 2)) (ref.extern 2)) +(assert_return (invoke "get-in-block-after-set" (ref.extern 3)) (ref.extern 3)) + +(assert_invalid + (module (func $uninit (local $x (ref extern)) (drop (local.get $x)))) + "uninitialized local" +) +(assert_invalid + (module + (func $uninit-after-end (param $p (ref extern)) + (local $x (ref extern)) + (block (local.set $x (local.get $p)) (drop (local.tee $x (local.get $p)))) + (drop (local.get $x)) + ) + ) + "uninitialized local" +) diff --git a/proposals/gc/ref_as.wast b/proposals/gc/ref_as.wast deleted file mode 100644 index ecfb017..0000000 --- a/proposals/gc/ref_as.wast +++ /dev/null @@ -1,78 +0,0 @@ -(module - (type $ft (func)) - (type $st (struct)) - (type $at (array i8)) - - (table 10 anyref) - - (elem declare func $f) - (func $f) - - (func (export "init") (param $x externref) - (table.set (i32.const 0) (ref.null any)) - (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new_default $st (rtt.canon $st))) - (table.set (i32.const 3) (array.new_default $at (i32.const 0) (rtt.canon $at))) - (table.set (i32.const 4) (ref.func $f)) - (table.set (i32.const 5) (rtt.canon $ft)) - (table.set (i32.const 6) (local.get $x)) - ) - - (func (export "ref_as_non_null") (param $i i32) - (drop (ref.as_non_null (table.get (local.get $i)))) - ) - (func (export "ref_as_i31") (param $i i32) - (drop (ref.as_i31 (table.get (local.get $i)))) - ) - (func (export "ref_as_data") (param $i i32) - (drop (ref.as_data (table.get (local.get $i)))) - ) - (func (export "ref_as_array") (param $i i32) - (drop (ref.as_array (table.get (local.get $i)))) - ) - (func (export "ref_as_func") (param $i i32) - (drop (ref.as_func (table.get (local.get $i)))) - ) -) - -(invoke "init" (ref.extern 0)) - -(assert_trap (invoke "ref_as_non_null" (i32.const 0)) "null reference") -(assert_return (invoke "ref_as_non_null" (i32.const 1))) -(assert_return (invoke "ref_as_non_null" (i32.const 2))) -(assert_return (invoke "ref_as_non_null" (i32.const 3))) -(assert_return (invoke "ref_as_non_null" (i32.const 4))) -(assert_return (invoke "ref_as_non_null" (i32.const 5))) -(assert_return (invoke "ref_as_non_null" (i32.const 6))) - -(assert_trap (invoke "ref_as_i31" (i32.const 0)) "cast failure") -(assert_return (invoke "ref_as_i31" (i32.const 1))) -(assert_trap (invoke "ref_as_i31" (i32.const 2)) "cast failure") -(assert_trap (invoke "ref_as_i31" (i32.const 3)) "cast failure") -(assert_trap (invoke "ref_as_i31" (i32.const 4)) "cast failure") -(assert_trap (invoke "ref_as_i31" (i32.const 5)) "cast failure") -(assert_trap (invoke "ref_as_i31" (i32.const 6)) "cast failure") - -(assert_trap (invoke "ref_as_data" (i32.const 0)) "cast failure") -(assert_trap (invoke "ref_as_data" (i32.const 1)) "cast failure") -(assert_return (invoke "ref_as_data" (i32.const 2))) -(assert_return (invoke "ref_as_data" (i32.const 3))) -(assert_trap (invoke "ref_as_data" (i32.const 4)) "cast failure") -(assert_trap (invoke "ref_as_data" (i32.const 5)) "cast failure") -(assert_trap (invoke "ref_as_data" (i32.const 6)) "cast failure") - -(assert_trap (invoke "ref_as_array" (i32.const 0)) "cast failure") -(assert_trap (invoke "ref_as_array" (i32.const 1)) "cast failure") -(assert_trap (invoke "ref_as_array" (i32.const 2)) "cast failure") -(assert_return (invoke "ref_as_array" (i32.const 3))) -(assert_trap (invoke "ref_as_array" (i32.const 4)) "cast failure") -(assert_trap (invoke "ref_as_array" (i32.const 5)) "cast failure") -(assert_trap (invoke "ref_as_array" (i32.const 6)) "cast failure") - -(assert_trap (invoke "ref_as_func" (i32.const 0)) "cast failure") -(assert_trap (invoke "ref_as_func" (i32.const 1)) "cast failure") -(assert_trap (invoke "ref_as_func" (i32.const 2)) "cast failure") -(assert_trap (invoke "ref_as_func" (i32.const 3)) "cast failure") -(assert_return (invoke "ref_as_func" (i32.const 4))) -(assert_trap (invoke "ref_as_func" (i32.const 5)) "cast failure") -(assert_trap (invoke "ref_as_func" (i32.const 6)) "cast failure") diff --git a/proposals/gc/ref_as_non_null.wast b/proposals/gc/ref_as_non_null.wast index ba5c454..6b3380f 100644 --- a/proposals/gc/ref_as_non_null.wast +++ b/proposals/gc/ref_as_non_null.wast @@ -2,10 +2,10 @@ (type $t (func (result i32))) (func $nn (param $r (ref $t)) (result i32) - (call_ref (ref.as_non_null (local.get $r))) + (call_ref $t (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))) + (call_ref $t (ref.as_non_null (local.get $r))) ) (elem func $f) diff --git a/proposals/gc/ref_cast.wast b/proposals/gc/ref_cast.wast index ec9c0e2..bca2219 100644 --- a/proposals/gc/ref_cast.wast +++ b/proposals/gc/ref_cast.wast @@ -1,3 +1,101 @@ +;; Abstract Types + +(module + (type $ft (func)) + (type $st (struct)) + (type $at (array i8)) + + (table 10 anyref) + + (elem declare func $f) + (func $f) + + (func (export "init") (param $x externref) + (table.set (i32.const 0) (ref.null any)) + (table.set (i32.const 1) (i31.new (i32.const 7))) + (table.set (i32.const 2) (struct.new_canon_default $st)) + (table.set (i32.const 3) (array.new_canon_default $at (i32.const 0))) + (table.set (i32.const 4) (extern.internalize (local.get $x))) + (table.set (i32.const 5) (ref.null i31)) + (table.set (i32.const 6) (ref.null struct)) + (table.set (i32.const 7) (ref.null none)) + ) + + (func (export "ref_cast_non_null") (param $i i32) + (drop (ref.as_non_null (table.get (local.get $i)))) + (drop (ref.cast null any (table.get (local.get $i)))) + ) + (func (export "ref_cast_null") (param $i i32) + (drop (ref.cast null any (table.get (local.get $i)))) + (drop (ref.cast null struct (table.get (local.get $i)))) + (drop (ref.cast null array (table.get (local.get $i)))) + (drop (ref.cast null i31 (table.get (local.get $i)))) + (drop (ref.cast null none (table.get (local.get $i)))) + ) + (func (export "ref_cast_i31") (param $i i32) + (drop (ref.cast i31 (table.get (local.get $i)))) + (drop (ref.cast null i31 (table.get (local.get $i)))) + ) + (func (export "ref_cast_struct") (param $i i32) + (drop (ref.cast struct (table.get (local.get $i)))) + (drop (ref.cast null struct (table.get (local.get $i)))) + ) + (func (export "ref_cast_array") (param $i i32) + (drop (ref.cast array (table.get (local.get $i)))) + (drop (ref.cast null array (table.get (local.get $i)))) + ) +) + +(invoke "init" (ref.extern 0)) + +(assert_trap (invoke "ref_cast_non_null" (i32.const 0)) "null reference") +(assert_return (invoke "ref_cast_non_null" (i32.const 1))) +(assert_return (invoke "ref_cast_non_null" (i32.const 2))) +(assert_return (invoke "ref_cast_non_null" (i32.const 3))) +(assert_return (invoke "ref_cast_non_null" (i32.const 4))) +(assert_trap (invoke "ref_cast_non_null" (i32.const 5)) "null reference") +(assert_trap (invoke "ref_cast_non_null" (i32.const 6)) "null reference") +(assert_trap (invoke "ref_cast_non_null" (i32.const 7)) "null reference") + +(assert_return (invoke "ref_cast_null" (i32.const 0))) +(assert_trap (invoke "ref_cast_null" (i32.const 1)) "cast failure") +(assert_trap (invoke "ref_cast_null" (i32.const 2)) "cast failure") +(assert_trap (invoke "ref_cast_null" (i32.const 3)) "cast failure") +(assert_trap (invoke "ref_cast_null" (i32.const 4)) "cast failure") +(assert_return (invoke "ref_cast_null" (i32.const 5))) +(assert_return (invoke "ref_cast_null" (i32.const 6))) +(assert_return (invoke "ref_cast_null" (i32.const 7))) + +(assert_trap (invoke "ref_cast_i31" (i32.const 0)) "cast failure") +(assert_return (invoke "ref_cast_i31" (i32.const 1))) +(assert_trap (invoke "ref_cast_i31" (i32.const 2)) "cast failure") +(assert_trap (invoke "ref_cast_i31" (i32.const 3)) "cast failure") +(assert_trap (invoke "ref_cast_i31" (i32.const 4)) "cast failure") +(assert_trap (invoke "ref_cast_i31" (i32.const 5)) "cast failure") +(assert_trap (invoke "ref_cast_i31" (i32.const 6)) "cast failure") +(assert_trap (invoke "ref_cast_i31" (i32.const 7)) "cast failure") + +(assert_trap (invoke "ref_cast_struct" (i32.const 0)) "cast failure") +(assert_trap (invoke "ref_cast_struct" (i32.const 1)) "cast failure") +(assert_return (invoke "ref_cast_struct" (i32.const 2))) +(assert_trap (invoke "ref_cast_struct" (i32.const 3)) "cast failure") +(assert_trap (invoke "ref_cast_struct" (i32.const 4)) "cast failure") +(assert_trap (invoke "ref_cast_struct" (i32.const 5)) "cast failure") +(assert_trap (invoke "ref_cast_struct" (i32.const 6)) "cast failure") +(assert_trap (invoke "ref_cast_struct" (i32.const 7)) "cast failure") + +(assert_trap (invoke "ref_cast_array" (i32.const 0)) "cast failure") +(assert_trap (invoke "ref_cast_array" (i32.const 1)) "cast failure") +(assert_trap (invoke "ref_cast_array" (i32.const 2)) "cast failure") +(assert_return (invoke "ref_cast_array" (i32.const 3))) +(assert_trap (invoke "ref_cast_array" (i32.const 4)) "cast failure") +(assert_trap (invoke "ref_cast_array" (i32.const 5)) "cast failure") +(assert_trap (invoke "ref_cast_array" (i32.const 6)) "cast failure") +(assert_trap (invoke "ref_cast_array" (i32.const 7)) "cast failure") + + +;; Concrete Types + (module (type $t0 (struct)) (type $t1 (sub $t0 (struct (field i32)))) @@ -8,74 +106,79 @@ (type $t0' (sub $t0 (struct))) (type $t4 (sub $t0' (struct (field i32 i32)))) - (global $t0 (rtt $t0) (rtt.canon $t0)) - (global $t0' (rtt $t0) (rtt.canon $t0)) - (global $t1 (rtt $t1) (rtt.canon $t1)) - (global $t1' (rtt $t1') (rtt.canon $t1')) - (global $t2 (rtt $t2) (rtt.canon $t2)) - (global $t2' (rtt $t2') (rtt.canon $t2')) - (global $t3 (rtt $t3) (rtt.canon $t3)) - (global $t4 (rtt $t4) (rtt.canon $t4)) - - (table 20 (ref null data)) + (table 20 (ref null struct)) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t4 (global.get $t4))) + (table.set (i32.const 0) (struct.new_canon_default $t0)) + (table.set (i32.const 10) (struct.new_canon_default $t0)) + (table.set (i32.const 1) (struct.new_canon_default $t1)) + (table.set (i32.const 11) (struct.new_canon_default $t1')) + (table.set (i32.const 2) (struct.new_canon_default $t2)) + (table.set (i32.const 12) (struct.new_canon_default $t2')) + (table.set (i32.const 3) (struct.new_canon_default $t3)) + (table.set (i32.const 4) (struct.new_canon_default $t4)) ) (func (export "test-sub") (call $init) - (drop (ref.cast (ref.null data) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 0)) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 1)) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 2)) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 3)) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 4)) (global.get $t0))) + (drop (ref.cast null $t0 (ref.null struct))) + (drop (ref.cast null $t0 (table.get (i32.const 0)))) + (drop (ref.cast null $t0 (table.get (i32.const 1)))) + (drop (ref.cast null $t0 (table.get (i32.const 2)))) + (drop (ref.cast null $t0 (table.get (i32.const 3)))) + (drop (ref.cast null $t0 (table.get (i32.const 4)))) + + (drop (ref.cast null $t0 (ref.null struct))) + (drop (ref.cast null $t1 (table.get (i32.const 1)))) + (drop (ref.cast null $t1 (table.get (i32.const 2)))) + + (drop (ref.cast null $t0 (ref.null struct))) + (drop (ref.cast null $t2 (table.get (i32.const 2)))) + + (drop (ref.cast null $t0 (ref.null struct))) + (drop (ref.cast null $t3 (table.get (i32.const 3)))) + + (drop (ref.cast null $t4 (table.get (i32.const 4)))) + + (drop (ref.cast $t0 (table.get (i32.const 0)))) + (drop (ref.cast $t0 (table.get (i32.const 1)))) + (drop (ref.cast $t0 (table.get (i32.const 2)))) + (drop (ref.cast $t0 (table.get (i32.const 3)))) + (drop (ref.cast $t0 (table.get (i32.const 4)))) - (drop (ref.cast (ref.null data) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 1)) (global.get $t1))) - (drop (ref.cast (table.get (i32.const 2)) (global.get $t1))) + (drop (ref.cast $t1 (table.get (i32.const 1)))) + (drop (ref.cast $t1 (table.get (i32.const 2)))) - (drop (ref.cast (ref.null data) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 2)) (global.get $t2))) + (drop (ref.cast $t2 (table.get (i32.const 2)))) - (drop (ref.cast (ref.null data) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 3)) (global.get $t3))) + (drop (ref.cast $t3 (table.get (i32.const 3)))) - (drop (ref.cast (ref.null data) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 4)) (global.get $t4))) + (drop (ref.cast $t4 (table.get (i32.const 4)))) ) (func (export "test-canon") (call $init) - (drop (ref.cast (table.get (i32.const 0)) (global.get $t0'))) - (drop (ref.cast (table.get (i32.const 1)) (global.get $t0'))) - (drop (ref.cast (table.get (i32.const 2)) (global.get $t0'))) - (drop (ref.cast (table.get (i32.const 3)) (global.get $t0'))) - (drop (ref.cast (table.get (i32.const 4)) (global.get $t0'))) + (drop (ref.cast $t0 (table.get (i32.const 0)))) + (drop (ref.cast $t0 (table.get (i32.const 1)))) + (drop (ref.cast $t0 (table.get (i32.const 2)))) + (drop (ref.cast $t0 (table.get (i32.const 3)))) + (drop (ref.cast $t0 (table.get (i32.const 4)))) - (drop (ref.cast (table.get (i32.const 10)) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 11)) (global.get $t0))) - (drop (ref.cast (table.get (i32.const 12)) (global.get $t0))) + (drop (ref.cast $t0 (table.get (i32.const 10)))) + (drop (ref.cast $t0 (table.get (i32.const 11)))) + (drop (ref.cast $t0 (table.get (i32.const 12)))) - (drop (ref.cast (table.get (i32.const 1)) (global.get $t1'))) - (drop (ref.cast (table.get (i32.const 2)) (global.get $t1'))) + (drop (ref.cast $t1' (table.get (i32.const 1)))) + (drop (ref.cast $t1' (table.get (i32.const 2)))) - (drop (ref.cast (table.get (i32.const 11)) (global.get $t1))) - (drop (ref.cast (table.get (i32.const 12)) (global.get $t1))) + (drop (ref.cast $t1 (table.get (i32.const 11)))) + (drop (ref.cast $t1 (table.get (i32.const 12)))) - (drop (ref.cast (table.get (i32.const 2)) (global.get $t2'))) + (drop (ref.cast $t2' (table.get (i32.const 2)))) - (drop (ref.cast (table.get (i32.const 12)) (global.get $t2))) + (drop (ref.cast $t2 (table.get (i32.const 12)))) ) ) diff --git a/proposals/gc/ref_eq.wast b/proposals/gc/ref_eq.wast index 51d5348..d7f3a90 100644 --- a/proposals/gc/ref_eq.wast +++ b/proposals/gc/ref_eq.wast @@ -15,17 +15,10 @@ (table.set (i32.const 2) (i31.new (i32.const 7))) (table.set (i32.const 3) (i31.new (i32.const 7))) (table.set (i32.const 4) (i31.new (i32.const 8))) - (table.set (i32.const 5) (struct.new_default $st (rtt.canon $st))) - (table.set (i32.const 6) (struct.new_default $st (rtt.canon $st))) - (table.set (i32.const 7) (array.new_default $at (i32.const 0) (rtt.canon $at))) - (table.set (i32.const 8) (array.new_default $at (i32.const 0) (rtt.canon $at))) - (table.set (i32.const 9) (rtt.canon $st)) - (table.set (i32.const 10) (rtt.canon $st)) - (table.set (i32.const 11) (rtt.canon $at)) - (table.set (i32.const 12) (rtt.canon $st-sub1)) - (table.set (i32.const 13) (rtt.canon $st-sub2)) - (table.set (i32.const 14) (rtt.canon $st'-sub1)) - (table.set (i32.const 15) (rtt.canon $st'-sub2)) + (table.set (i32.const 5) (struct.new_canon_default $st)) + (table.set (i32.const 6) (struct.new_canon_default $st)) + (table.set (i32.const 7) (array.new_canon_default $at (i32.const 0))) + (table.set (i32.const 8) (array.new_canon_default $at (i32.const 0))) ) (func (export "eq") (param $i i32) (param $j i32) (result i32) @@ -44,13 +37,6 @@ (assert_return (invoke "eq" (i32.const 0) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 0) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 0) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 0) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 1)) (assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1)) @@ -61,13 +47,6 @@ (assert_return (invoke "eq" (i32.const 1) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 1) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 1) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 1) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 2) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 2) (i32.const 1)) (i32.const 0)) @@ -78,13 +57,6 @@ (assert_return (invoke "eq" (i32.const 2) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 2) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 2) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 2) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 3) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 3) (i32.const 1)) (i32.const 0)) @@ -95,13 +67,6 @@ (assert_return (invoke "eq" (i32.const 3) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 3) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 3) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 3) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 4) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 4) (i32.const 1)) (i32.const 0)) @@ -112,13 +77,6 @@ (assert_return (invoke "eq" (i32.const 4) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 4) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 4) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 4) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 5) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 5) (i32.const 1)) (i32.const 0)) @@ -129,13 +87,6 @@ (assert_return (invoke "eq" (i32.const 5) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 5) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 5) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 5) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 6) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 6) (i32.const 1)) (i32.const 0)) @@ -146,13 +97,6 @@ (assert_return (invoke "eq" (i32.const 6) (i32.const 6)) (i32.const 1)) (assert_return (invoke "eq" (i32.const 6) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 6) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 6) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 7) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 7) (i32.const 1)) (i32.const 0)) @@ -163,13 +107,6 @@ (assert_return (invoke "eq" (i32.const 7) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 7) (i32.const 7)) (i32.const 1)) (assert_return (invoke "eq" (i32.const 7) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 7) (i32.const 15)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 8) (i32.const 0)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 8) (i32.const 1)) (i32.const 0)) @@ -180,132 +117,6 @@ (assert_return (invoke "eq" (i32.const 8) (i32.const 6)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 8) (i32.const 7)) (i32.const 0)) (assert_return (invoke "eq" (i32.const 8) (i32.const 8)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 8) (i32.const 15)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 9) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 9)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 10)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 9) (i32.const 15)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 10) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 9)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 10)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 10) (i32.const 15)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 11) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 11)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 11) (i32.const 15)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 12) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 12)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 13)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 12) (i32.const 15)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 13) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 12)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 13)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 14)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 13) (i32.const 15)) (i32.const 0)) - -(assert_return (invoke "eq" (i32.const 14) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 14)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 14) (i32.const 15)) (i32.const 1)) - -(assert_return (invoke "eq" (i32.const 15) (i32.const 0)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 1)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 2)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 3)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 4)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 5)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 6)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 7)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 8)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 9)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 10)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 11)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 12)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 13)) (i32.const 0)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 14)) (i32.const 1)) -(assert_return (invoke "eq" (i32.const 15) (i32.const 15)) (i32.const 1)) (assert_invalid (module diff --git a/proposals/gc/ref_is.wast b/proposals/gc/ref_is.wast deleted file mode 100644 index 4cee91b..0000000 --- a/proposals/gc/ref_is.wast +++ /dev/null @@ -1,78 +0,0 @@ -(module - (type $ft (func)) - (type $st (struct)) - (type $at (array i8)) - - (table 10 anyref) - - (elem declare func $f) - (func $f) - - (func (export "init") (param $x externref) - (table.set (i32.const 0) (ref.null any)) - (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new_default $st (rtt.canon $st))) - (table.set (i32.const 3) (array.new_default $at (i32.const 0) (rtt.canon $at))) - (table.set (i32.const 4) (ref.func $f)) - (table.set (i32.const 5) (rtt.canon $ft)) - (table.set (i32.const 6) (local.get $x)) - ) - - (func (export "ref_is_null") (param $i i32) (result i32) - (ref.is_null (table.get (local.get $i))) - ) - (func (export "ref_is_i31") (param $i i32) (result i32) - (ref.is_i31 (table.get (local.get $i))) - ) - (func (export "ref_is_data") (param $i i32) (result i32) - (ref.is_data (table.get (local.get $i))) - ) - (func (export "ref_is_array") (param $i i32) (result i32) - (ref.is_array (table.get (local.get $i))) - ) - (func (export "ref_is_func") (param $i i32) (result i32) - (ref.is_func (table.get (local.get $i))) - ) -) - -(invoke "init" (ref.extern 0)) - -(assert_return (invoke "ref_is_null" (i32.const 0)) (i32.const 1)) -(assert_return (invoke "ref_is_null" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ref_is_null" (i32.const 2)) (i32.const 0)) -(assert_return (invoke "ref_is_null" (i32.const 3)) (i32.const 0)) -(assert_return (invoke "ref_is_null" (i32.const 4)) (i32.const 0)) -(assert_return (invoke "ref_is_null" (i32.const 5)) (i32.const 0)) -(assert_return (invoke "ref_is_null" (i32.const 6)) (i32.const 0)) - -(assert_return (invoke "ref_is_i31" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "ref_is_i31" (i32.const 1)) (i32.const 1)) -(assert_return (invoke "ref_is_i31" (i32.const 2)) (i32.const 0)) -(assert_return (invoke "ref_is_i31" (i32.const 3)) (i32.const 0)) -(assert_return (invoke "ref_is_i31" (i32.const 4)) (i32.const 0)) -(assert_return (invoke "ref_is_i31" (i32.const 5)) (i32.const 0)) -(assert_return (invoke "ref_is_i31" (i32.const 6)) (i32.const 0)) - -(assert_return (invoke "ref_is_data" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "ref_is_data" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ref_is_data" (i32.const 2)) (i32.const 1)) -(assert_return (invoke "ref_is_data" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "ref_is_data" (i32.const 4)) (i32.const 0)) -(assert_return (invoke "ref_is_data" (i32.const 5)) (i32.const 0)) -(assert_return (invoke "ref_is_data" (i32.const 6)) (i32.const 0)) - -(assert_return (invoke "ref_is_array" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "ref_is_array" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ref_is_array" (i32.const 2)) (i32.const 0)) -(assert_return (invoke "ref_is_array" (i32.const 3)) (i32.const 1)) -(assert_return (invoke "ref_is_array" (i32.const 4)) (i32.const 0)) -(assert_return (invoke "ref_is_array" (i32.const 5)) (i32.const 0)) -(assert_return (invoke "ref_is_array" (i32.const 6)) (i32.const 0)) - -(assert_return (invoke "ref_is_func" (i32.const 0)) (i32.const 0)) -(assert_return (invoke "ref_is_func" (i32.const 1)) (i32.const 0)) -(assert_return (invoke "ref_is_func" (i32.const 2)) (i32.const 0)) -(assert_return (invoke "ref_is_func" (i32.const 3)) (i32.const 0)) -(assert_return (invoke "ref_is_func" (i32.const 4)) (i32.const 1)) -(assert_return (invoke "ref_is_func" (i32.const 5)) (i32.const 0)) -(assert_return (invoke "ref_is_func" (i32.const 6)) (i32.const 0)) diff --git a/proposals/gc/ref_null.wast b/proposals/gc/ref_null.wast index ab3a8b4..1ffd03f 100644 --- a/proposals/gc/ref_null.wast +++ b/proposals/gc/ref_null.wast @@ -1,14 +1,63 @@ (module (type $t (func)) - (func (export "externref") (result externref) (ref.null extern)) + (func (export "anyref") (result anyref) (ref.null any)) (func (export "funcref") (result funcref) (ref.null func)) (func (export "ref") (result (ref null $t)) (ref.null $t)) - (global externref (ref.null extern)) + (global anyref (ref.null any)) (global funcref (ref.null func)) (global (ref null $t) (ref.null $t)) ) -(assert_return (invoke "externref") (ref.null extern)) +(assert_return (invoke "anyref") (ref.null any)) (assert_return (invoke "funcref") (ref.null func)) (assert_return (invoke "ref") (ref.null)) + + +(module + (type $t (func)) + (global $null nullref (ref.null none)) + (global $nullfunc nullfuncref (ref.null nofunc)) + (global $nullextern nullexternref (ref.null noextern)) + (func (export "anyref") (result anyref) (global.get $null)) + (func (export "nullref") (result nullref) (global.get $null)) + (func (export "funcref") (result funcref) (global.get $nullfunc)) + (func (export "nullfuncref") (result nullfuncref) (global.get $nullfunc)) + (func (export "externref") (result externref) (global.get $nullextern)) + (func (export "nullexternref") (result nullexternref) (global.get $nullextern)) + (func (export "ref") (result (ref null $t)) (global.get $nullfunc)) + + (global anyref (ref.null any)) + (global anyref (ref.null none)) + (global funcref (ref.null func)) + (global funcref (ref.null nofunc)) + (global externref (ref.null extern)) + (global externref (ref.null noextern)) + (global nullref (ref.null none)) + (global nullfuncref (ref.null nofunc)) + (global nullexternref (ref.null noextern)) + (global (ref null $t) (ref.null $t)) + (global (ref null $t) (ref.null nofunc)) +) + +(assert_return (invoke "anyref") (ref.null any)) +(assert_return (invoke "anyref") (ref.null none)) +(assert_return (invoke "anyref") (ref.null)) +(assert_return (invoke "nullref") (ref.null any)) +(assert_return (invoke "nullref") (ref.null none)) +(assert_return (invoke "nullref") (ref.null)) +(assert_return (invoke "funcref") (ref.null func)) +(assert_return (invoke "funcref") (ref.null nofunc)) +(assert_return (invoke "funcref") (ref.null)) +(assert_return (invoke "nullfuncref") (ref.null func)) +(assert_return (invoke "nullfuncref") (ref.null nofunc)) +(assert_return (invoke "nullfuncref") (ref.null)) +(assert_return (invoke "externref") (ref.null extern)) +(assert_return (invoke "externref") (ref.null noextern)) +(assert_return (invoke "externref") (ref.null)) +(assert_return (invoke "nullexternref") (ref.null extern)) +(assert_return (invoke "nullexternref") (ref.null noextern)) +(assert_return (invoke "nullexternref") (ref.null)) +(assert_return (invoke "ref") (ref.null func)) +(assert_return (invoke "ref") (ref.null nofunc)) +(assert_return (invoke "ref") (ref.null)) diff --git a/proposals/gc/ref_test.wast b/proposals/gc/ref_test.wast index fb6047f..4370d16 100644 --- a/proposals/gc/ref_test.wast +++ b/proposals/gc/ref_test.wast @@ -1,3 +1,184 @@ +;; Abstract Types + +(module + (type $ft (func)) + (type $st (struct)) + (type $at (array i8)) + + (table $ta 10 anyref) + (table $tf 10 funcref) + (table $te 10 externref) + + (elem declare func $f) + (func $f) + + (func (export "init") (param $x externref) + (table.set $ta (i32.const 0) (ref.null any)) + (table.set $ta (i32.const 1) (ref.null struct)) + (table.set $ta (i32.const 2) (ref.null none)) + (table.set $ta (i32.const 3) (i31.new (i32.const 7))) + (table.set $ta (i32.const 4) (struct.new_canon_default $st)) + (table.set $ta (i32.const 5) (array.new_canon_default $at (i32.const 0))) + (table.set $ta (i32.const 6) (extern.internalize (local.get $x))) + (table.set $ta (i32.const 7) (extern.internalize (ref.null extern))) + + (table.set $tf (i32.const 0) (ref.null nofunc)) + (table.set $tf (i32.const 1) (ref.null func)) + (table.set $tf (i32.const 2) (ref.func $f)) + + (table.set $te (i32.const 0) (ref.null noextern)) + (table.set $te (i32.const 1) (ref.null extern)) + (table.set $te (i32.const 2) (local.get $x)) + (table.set $te (i32.const 3) (extern.externalize (i31.new (i32.const 8)))) + (table.set $te (i32.const 4) (extern.externalize (struct.new_canon_default $st))) + (table.set $te (i32.const 5) (extern.externalize (ref.null any))) + ) + + (func (export "ref_test_null_data") (param $i i32) (result i32) + (i32.add + (ref.is_null (table.get $ta (local.get $i))) + (ref.test null none (table.get $ta (local.get $i))) + ) + ) + (func (export "ref_test_any") (param $i i32) (result i32) + (i32.add + (ref.test any (table.get $ta (local.get $i))) + (ref.test null any (table.get $ta (local.get $i))) + ) + ) + (func (export "ref_test_eq") (param $i i32) (result i32) + (i32.add + (ref.test eq (table.get $ta (local.get $i))) + (ref.test null eq (table.get $ta (local.get $i))) + ) + ) + (func (export "ref_test_i31") (param $i i32) (result i32) + (i32.add + (ref.test i31 (table.get $ta (local.get $i))) + (ref.test null i31 (table.get $ta (local.get $i))) + ) + ) + (func (export "ref_test_struct") (param $i i32) (result i32) + (i32.add + (ref.test struct (table.get $ta (local.get $i))) + (ref.test null struct (table.get $ta (local.get $i))) + ) + ) + (func (export "ref_test_array") (param $i i32) (result i32) + (i32.add + (ref.test array (table.get $ta (local.get $i))) + (ref.test null array (table.get $ta (local.get $i))) + ) + ) + + (func (export "ref_test_null_func") (param $i i32) (result i32) + (i32.add + (ref.is_null (table.get $tf (local.get $i))) + (ref.test null nofunc (table.get $tf (local.get $i))) + ) + ) + (func (export "ref_test_func") (param $i i32) (result i32) + (i32.add + (ref.test func (table.get $tf (local.get $i))) + (ref.test null func (table.get $tf (local.get $i))) + ) + ) + + (func (export "ref_test_null_extern") (param $i i32) (result i32) + (i32.add + (ref.is_null (table.get $te (local.get $i))) + (ref.test null noextern (table.get $te (local.get $i))) + ) + ) + (func (export "ref_test_extern") (param $i i32) (result i32) + (i32.add + (ref.test extern (table.get $te (local.get $i))) + (ref.test null extern (table.get $te (local.get $i))) + ) + ) +) + +(invoke "init" (ref.extern 0)) + +(assert_return (invoke "ref_test_null_data" (i32.const 0)) (i32.const 2)) +(assert_return (invoke "ref_test_null_data" (i32.const 1)) (i32.const 2)) +(assert_return (invoke "ref_test_null_data" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "ref_test_null_data" (i32.const 3)) (i32.const 0)) +(assert_return (invoke "ref_test_null_data" (i32.const 4)) (i32.const 0)) +(assert_return (invoke "ref_test_null_data" (i32.const 5)) (i32.const 0)) +(assert_return (invoke "ref_test_null_data" (i32.const 6)) (i32.const 0)) +(assert_return (invoke "ref_test_null_data" (i32.const 7)) (i32.const 2)) + +(assert_return (invoke "ref_test_any" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_any" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_any" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "ref_test_any" (i32.const 3)) (i32.const 2)) +(assert_return (invoke "ref_test_any" (i32.const 4)) (i32.const 2)) +(assert_return (invoke "ref_test_any" (i32.const 5)) (i32.const 2)) +(assert_return (invoke "ref_test_any" (i32.const 6)) (i32.const 2)) +(assert_return (invoke "ref_test_any" (i32.const 7)) (i32.const 1)) + +(assert_return (invoke "ref_test_eq" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_eq" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_eq" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "ref_test_eq" (i32.const 3)) (i32.const 2)) +(assert_return (invoke "ref_test_eq" (i32.const 4)) (i32.const 2)) +(assert_return (invoke "ref_test_eq" (i32.const 5)) (i32.const 2)) +(assert_return (invoke "ref_test_eq" (i32.const 6)) (i32.const 0)) +(assert_return (invoke "ref_test_eq" (i32.const 7)) (i32.const 1)) + +(assert_return (invoke "ref_test_i31" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_i31" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_i31" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "ref_test_i31" (i32.const 3)) (i32.const 2)) +(assert_return (invoke "ref_test_i31" (i32.const 4)) (i32.const 0)) +(assert_return (invoke "ref_test_i31" (i32.const 5)) (i32.const 0)) +(assert_return (invoke "ref_test_i31" (i32.const 6)) (i32.const 0)) +(assert_return (invoke "ref_test_i31" (i32.const 7)) (i32.const 1)) + +(assert_return (invoke "ref_test_struct" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_struct" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_struct" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "ref_test_struct" (i32.const 3)) (i32.const 0)) +(assert_return (invoke "ref_test_struct" (i32.const 4)) (i32.const 2)) +(assert_return (invoke "ref_test_struct" (i32.const 5)) (i32.const 0)) +(assert_return (invoke "ref_test_struct" (i32.const 6)) (i32.const 0)) +(assert_return (invoke "ref_test_struct" (i32.const 7)) (i32.const 1)) + +(assert_return (invoke "ref_test_array" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_array" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_array" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "ref_test_array" (i32.const 3)) (i32.const 0)) +(assert_return (invoke "ref_test_array" (i32.const 4)) (i32.const 0)) +(assert_return (invoke "ref_test_array" (i32.const 5)) (i32.const 2)) +(assert_return (invoke "ref_test_array" (i32.const 6)) (i32.const 0)) +(assert_return (invoke "ref_test_array" (i32.const 7)) (i32.const 1)) + +(assert_return (invoke "ref_test_null_func" (i32.const 0)) (i32.const 2)) +(assert_return (invoke "ref_test_null_func" (i32.const 1)) (i32.const 2)) +(assert_return (invoke "ref_test_null_func" (i32.const 2)) (i32.const 0)) + +(assert_return (invoke "ref_test_func" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_func" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_func" (i32.const 2)) (i32.const 2)) + +(assert_return (invoke "ref_test_null_extern" (i32.const 0)) (i32.const 2)) +(assert_return (invoke "ref_test_null_extern" (i32.const 1)) (i32.const 2)) +(assert_return (invoke "ref_test_null_extern" (i32.const 2)) (i32.const 0)) +(assert_return (invoke "ref_test_null_extern" (i32.const 3)) (i32.const 0)) +(assert_return (invoke "ref_test_null_extern" (i32.const 4)) (i32.const 0)) +(assert_return (invoke "ref_test_null_extern" (i32.const 5)) (i32.const 2)) + +(assert_return (invoke "ref_test_extern" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "ref_test_extern" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "ref_test_extern" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "ref_test_extern" (i32.const 3)) (i32.const 2)) +(assert_return (invoke "ref_test_extern" (i32.const 4)) (i32.const 2)) +(assert_return (invoke "ref_test_extern" (i32.const 5)) (i32.const 1)) + + +;; Concrete Types + (module (type $t0 (struct)) (type $t1 (sub $t0 (struct (field i32)))) @@ -8,72 +189,108 @@ (type $t0' (sub $t0 (struct))) (type $t4 (sub $t0' (struct (field i32 i32)))) - (global $t0 (rtt $t0) (rtt.canon $t0)) - (global $t0' (rtt $t0) (rtt.canon $t0)) - (global $t1 (rtt $t1) (rtt.canon $t1)) - (global $t1' (rtt $t1') (rtt.canon $t1')) - (global $t2 (rtt $t2) (rtt.canon $t2)) - (global $t2' (rtt $t2') (rtt.canon $t2')) - (global $t3 (rtt $t3) (rtt.canon $t3)) - (global $t4 (rtt $t4) (rtt.canon $t4)) - - (table 20 (ref null data)) + (table 20 (ref null struct)) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t4 (global.get $t4))) + (table.set (i32.const 0) (struct.new_canon_default $t0)) + (table.set (i32.const 10) (struct.new_canon_default $t0)) + (table.set (i32.const 1) (struct.new_canon_default $t1)) + (table.set (i32.const 11) (struct.new_canon_default $t1')) + (table.set (i32.const 2) (struct.new_canon_default $t2)) + (table.set (i32.const 12) (struct.new_canon_default $t2')) + (table.set (i32.const 3) (struct.new_canon_default $t3)) + (table.set (i32.const 4) (struct.new_canon_default $t4)) ) (func (export "test-sub") (call $init) (block $l ;; must hold - (br_if $l (i32.eqz (ref.test (table.get (i32.const 0)) (global.get $t0)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 1)) (global.get $t0)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 2)) (global.get $t0)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 3)) (global.get $t0)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 4)) (global.get $t0)))) + (br_if $l (i32.eqz (ref.test null $t0 (ref.null struct)))) + (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 0))))) + (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 3))))) + (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 4))))) + + (br_if $l (i32.eqz (ref.test null $t1 (ref.null struct)))) + (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test null $t1 (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test null $t1 (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test null $t2 (ref.null struct)))) + (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test null $t2 (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 1)) (global.get $t1)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 2)) (global.get $t1)))) + (br_if $l (i32.eqz (ref.test null $t3 (ref.null struct)))) + (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test null $t3 (table.get (i32.const 3))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 2)) (global.get $t2)))) + (br_if $l (i32.eqz (ref.test null $t4 (ref.null struct)))) + (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test null $t4 (table.get (i32.const 4))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 3)) (global.get $t3)))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 0))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 3))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 4))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 4)) (global.get $t4)))) + (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test $t2 (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test $t3 (table.get (i32.const 3))))) + + (br_if $l (i32.eqz (ref.test $t4 (table.get (i32.const 4))))) ;; must not hold - (br_if $l (ref.test (ref.null data) (global.get $t0))) - (br_if $l (ref.test (ref.null data) (global.get $t1))) - (br_if $l (ref.test (ref.null data) (global.get $t2))) - (br_if $l (ref.test (ref.null data) (global.get $t3))) - (br_if $l (ref.test (ref.null data) (global.get $t4))) - - (br_if $l (ref.test (table.get (i32.const 0)) (global.get $t1))) - (br_if $l (ref.test (table.get (i32.const 3)) (global.get $t1))) - (br_if $l (ref.test (table.get (i32.const 4)) (global.get $t1))) - - (br_if $l (ref.test (table.get (i32.const 0)) (global.get $t2))) - (br_if $l (ref.test (table.get (i32.const 1)) (global.get $t2))) - (br_if $l (ref.test (table.get (i32.const 3)) (global.get $t2))) - (br_if $l (ref.test (table.get (i32.const 4)) (global.get $t2))) - - (br_if $l (ref.test (table.get (i32.const 0)) (global.get $t3))) - (br_if $l (ref.test (table.get (i32.const 1)) (global.get $t3))) - (br_if $l (ref.test (table.get (i32.const 2)) (global.get $t3))) - (br_if $l (ref.test (table.get (i32.const 4)) (global.get $t3))) - - (br_if $l (ref.test (table.get (i32.const 0)) (global.get $t4))) - (br_if $l (ref.test (table.get (i32.const 1)) (global.get $t4))) - (br_if $l (ref.test (table.get (i32.const 2)) (global.get $t4))) - (br_if $l (ref.test (table.get (i32.const 3)) (global.get $t4))) + (br_if $l (ref.test $t0 (ref.null struct))) + (br_if $l (ref.test $t1 (ref.null struct))) + (br_if $l (ref.test $t2 (ref.null struct))) + (br_if $l (ref.test $t3 (ref.null struct))) + (br_if $l (ref.test $t4 (ref.null struct))) + + (br_if $l (ref.test $t1 (table.get (i32.const 0)))) + (br_if $l (ref.test $t1 (table.get (i32.const 3)))) + (br_if $l (ref.test $t1 (table.get (i32.const 4)))) + + (br_if $l (ref.test $t2 (table.get (i32.const 0)))) + (br_if $l (ref.test $t2 (table.get (i32.const 1)))) + (br_if $l (ref.test $t2 (table.get (i32.const 3)))) + (br_if $l (ref.test $t2 (table.get (i32.const 4)))) + + (br_if $l (ref.test $t3 (table.get (i32.const 0)))) + (br_if $l (ref.test $t3 (table.get (i32.const 1)))) + (br_if $l (ref.test $t3 (table.get (i32.const 2)))) + (br_if $l (ref.test $t3 (table.get (i32.const 4)))) + + (br_if $l (ref.test $t4 (table.get (i32.const 0)))) + (br_if $l (ref.test $t4 (table.get (i32.const 1)))) + (br_if $l (ref.test $t4 (table.get (i32.const 2)))) + (br_if $l (ref.test $t4 (table.get (i32.const 3)))) (return) ) @@ -83,25 +300,25 @@ (func (export "test-canon") (call $init) (block $l - (br_if $l (i32.eqz (ref.test (table.get (i32.const 0)) (global.get $t0')))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 1)) (global.get $t0')))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 2)) (global.get $t0')))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 3)) (global.get $t0')))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 4)) (global.get $t0')))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 0))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 3))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 4))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 10)) (global.get $t0)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 11)) (global.get $t0)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 12)) (global.get $t0)))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 10))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 11))))) + (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 12))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 1)) (global.get $t1')))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 2)) (global.get $t1')))) + (br_if $l (i32.eqz (ref.test $t1' (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test $t1' (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 11)) (global.get $t1)))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 12)) (global.get $t1)))) + (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 11))))) + (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 12))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 2)) (global.get $t2')))) + (br_if $l (i32.eqz (ref.test $t2' (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test (table.get (i32.const 12)) (global.get $t2)))) + (br_if $l (i32.eqz (ref.test $t2 (table.get (i32.const 12))))) (return) ) diff --git a/proposals/gc/return_call_ref.wast b/proposals/gc/return_call_ref.wast index 8e7aac8..353811f 100644 --- a/proposals/gc/return_call_ref.wast +++ b/proposals/gc/return_call_ref.wast @@ -59,48 +59,48 @@ ;; Typing (func (export "type-i32") (result i32) - (return_call_ref (global.get $const-i32)) + (return_call_ref $-i32 (global.get $const-i32)) ) (func (export "type-i64") (result i64) - (return_call_ref (global.get $const-i64)) + (return_call_ref $-i64 (global.get $const-i64)) ) (func (export "type-f32") (result f32) - (return_call_ref (global.get $const-f32)) + (return_call_ref $-f32 (global.get $const-f32)) ) (func (export "type-f64") (result f64) - (return_call_ref (global.get $const-f64)) + (return_call_ref $-f64 (global.get $const-f64)) ) (func (export "type-first-i32") (result i32) - (return_call_ref (i32.const 32) (global.get $id-i32)) + (return_call_ref $i32-i32 (i32.const 32) (global.get $id-i32)) ) (func (export "type-first-i64") (result i64) - (return_call_ref (i64.const 64) (global.get $id-i64)) + (return_call_ref $i64-i64 (i64.const 64) (global.get $id-i64)) ) (func (export "type-first-f32") (result f32) - (return_call_ref (f32.const 1.32) (global.get $id-f32)) + (return_call_ref $f32-f32 (f32.const 1.32) (global.get $id-f32)) ) (func (export "type-first-f64") (result f64) - (return_call_ref (f64.const 1.64) (global.get $id-f64)) + (return_call_ref $f64-f64 (f64.const 1.64) (global.get $id-f64)) ) (func (export "type-second-i32") (result i32) - (return_call_ref (f32.const 32.1) (i32.const 32) (global.get $f32-i32)) + (return_call_ref $f32-i32 (f32.const 32.1) (i32.const 32) (global.get $f32-i32)) ) (func (export "type-second-i64") (result i64) - (return_call_ref (i32.const 32) (i64.const 64) (global.get $i32-i64)) + (return_call_ref $i32-i64 (i32.const 32) (i64.const 64) (global.get $i32-i64)) ) (func (export "type-second-f32") (result f32) - (return_call_ref (f64.const 64) (f32.const 32) (global.get $f64-f32)) + (return_call_ref $f64-f32 (f64.const 64) (f32.const 32) (global.get $f64-f32)) ) (func (export "type-second-f64") (result f64) - (return_call_ref (i64.const 64) (f64.const 64.1) (global.get $i64-f64)) + (return_call_ref $i64-f64 (i64.const 64) (f64.const 64.1) (global.get $i64-f64)) ) ;; Null (func (export "null") - (return_call_ref (ref.null $proc)) + (return_call_ref $proc (ref.null $proc)) ) ;; Recursion @@ -112,7 +112,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (local.get 1)) (else - (return_call_ref + (return_call_ref $i64i64-i64 (i64.sub (local.get 0) (i64.const 1)) (i64.mul (local.get 0) (local.get 1)) (global.get $fac-acc) @@ -128,7 +128,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (local.get 0)) (else - (return_call_ref + (return_call_ref $i64-i64 (i64.sub (local.get 0) (i64.const 1)) (global.get $count) ) @@ -144,7 +144,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (i64.const 44)) (else - (return_call_ref + (return_call_ref $i64-i64 (i64.sub (local.get 0) (i64.const 1)) (global.get $odd) ) @@ -156,7 +156,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (i64.const 99)) (else - (return_call_ref + (return_call_ref $i64-i64 (i64.sub (local.get 0) (i64.const 1)) (global.get $even) ) @@ -212,24 +212,29 @@ (module (type $t (func)) + (type $t1 (func (result (ref $t)))) + (type $t2 (func (result (ref null $t)))) + (type $t3 (func (result (ref func)))) + (type $t4 (func (result (ref null func)))) (elem declare func $f11 $f22 $f33 $f44) - (func $f11 (result (ref $t)) (return_call_ref (ref.func $f11))) - (func $f21 (result (ref null $t)) (return_call_ref (ref.func $f11))) - (func $f22 (result (ref null $t)) (return_call_ref (ref.func $f22))) - (func $f31 (result (ref func)) (return_call_ref (ref.func $f11))) - (func $f33 (result (ref func)) (return_call_ref (ref.func $f33))) - (func $f41 (result (ref null func)) (return_call_ref (ref.func $f11))) - (func $f42 (result (ref null func)) (return_call_ref (ref.func $f22))) - (func $f43 (result (ref null func)) (return_call_ref (ref.func $f33))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f11 (result (ref $t)) (return_call_ref $t1 (ref.func $f11))) + (func $f21 (result (ref null $t)) (return_call_ref $t1 (ref.func $f11))) + (func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22))) + (func $f31 (result (ref func)) (return_call_ref $t1 (ref.func $f11))) + (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) + (func $f41 (result (ref null func)) (return_call_ref $t1 (ref.func $f11))) + (func $f42 (result (ref null func)) (return_call_ref $t2 (ref.func $f22))) + (func $f43 (result (ref null func)) (return_call_ref $t3 (ref.func $f33))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) (assert_invalid (module (type $t (func)) + (type $t2 (func (result (ref null $t)))) (elem declare func $f22) - (func $f12 (result (ref $t)) (return_call_ref (ref.func $f22))) - (func $f22 (result (ref null $t)) (return_call_ref (ref.func $f22))) + (func $f12 (result (ref $t)) (return_call_ref $t2 (ref.func $f22))) + (func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22))) ) "type mismatch" ) @@ -237,9 +242,10 @@ (assert_invalid (module (type $t (func)) + (type $t3 (func (result (ref func)))) (elem declare func $f33) - (func $f13 (result (ref $t)) (return_call_ref (ref.func $f33))) - (func $f33 (result (ref func)) (return_call_ref (ref.func $f33))) + (func $f13 (result (ref $t)) (return_call_ref $t3 (ref.func $f33))) + (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) ) "type mismatch" ) @@ -247,9 +253,10 @@ (assert_invalid (module (type $t (func)) + (type $t4 (func (result (ref null func)))) (elem declare func $f44) - (func $f14 (result (ref $t)) (return_call_ref (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f14 (result (ref $t)) (return_call_ref $t4 (ref.func $f44))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) "type mismatch" ) @@ -257,9 +264,10 @@ (assert_invalid (module (type $t (func)) + (type $t3 (func (result (ref func)))) (elem declare func $f33) - (func $f23 (result (ref null $t)) (return_call_ref (ref.func $f33))) - (func $f33 (result (ref func)) (return_call_ref (ref.func $f33))) + (func $f23 (result (ref null $t)) (return_call_ref $t3 (ref.func $f33))) + (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) ) "type mismatch" ) @@ -267,18 +275,20 @@ (assert_invalid (module (type $t (func)) + (type $t4 (func (result (ref null func)))) (elem declare func $f44) - (func $f24 (result (ref null $t)) (return_call_ref (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f24 (result (ref null $t)) (return_call_ref $t4 (ref.func $f44))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) "type mismatch" ) (assert_invalid (module + (type $t4 (func (result (ref null func)))) (elem declare func $f44) - (func $f34 (result (ref func)) (return_call_ref (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f34 (result (ref func)) (return_call_ref $t4 (ref.func $f44))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) "type mismatch" ) @@ -287,34 +297,37 @@ ;; Unreachable typing. (module + (type $t (func (result i32))) (func (export "unreachable") (result i32) (unreachable) - (return_call_ref) + (return_call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (return_call_ref) + (return_call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i32.const 0) (ref.func $f) - (return_call_ref) + (return_call_ref $t) (i32.const 0) ) ) @@ -323,13 +336,14 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i64.const 0) (ref.func $f) - (return_call_ref) + (return_call_ref $t) ) ) "type mismatch" @@ -338,12 +352,13 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (return_call_ref) + (return_call_ref $t) (i64.const 0) ) ) @@ -352,8 +367,9 @@ (assert_invalid (module + (type $t (func)) (func $f (param $r externref) - (return_call_ref (local.get $r)) + (return_call_ref $t (local.get $r)) ) ) "type mismatch" diff --git a/proposals/gc/struct.wast b/proposals/gc/struct.wast index 1e001f7..bbd2c94 100644 --- a/proposals/gc/struct.wast +++ b/proposals/gc/struct.wast @@ -55,18 +55,18 @@ (module (type $vec (struct (field f32) (field $y (mut f32)) (field $z f32))) - (global (ref $vec) (struct.new $vec (f32.const 1) (f32.const 2) (f32.const 3) (rtt.canon $vec))) - (global (ref $vec) (struct.new_default $vec (rtt.canon $vec))) + (global (ref $vec) (struct.new_canon $vec (f32.const 1) (f32.const 2) (f32.const 3))) + (global (ref $vec) (struct.new_canon_default $vec)) (func (export "new") (result anyref) - (struct.new_default $vec (rtt.canon $vec)) + (struct.new_canon_default $vec) ) (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 $vec (rtt.canon $vec))) + (call $get_0 (struct.new_canon_default $vec)) ) (func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32) @@ -74,7 +74,7 @@ (struct.get $vec $y (local.get $v)) ) (func (export "set_get_y") (param $y f32) (result f32) - (call $set_get_y (struct.new_default $vec (rtt.canon $vec)) (local.get $y)) + (call $set_get_y (struct.new_canon_default $vec) (local.get $y)) ) (func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32) @@ -82,11 +82,11 @@ (struct.get $vec $y (local.get $v)) ) (func (export "set_get_1") (param $y f32) (result f32) - (call $set_get_1 (struct.new_default $vec (rtt.canon $vec)) (local.get $y)) + (call $set_get_1 (struct.new_canon_default $vec) (local.get $y)) ) ) -(assert_return (invoke "new") (ref.data)) +(assert_return (invoke "new") (ref.struct)) (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)) @@ -116,22 +116,3 @@ (assert_trap (invoke "struct.get-null") "null structure") (assert_trap (invoke "struct.set-null") "null structure") - -(assert_invalid - (module - (type $t (struct (field i32 (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 (mut i32)))) - (func (export "struct.new_default-null") - (local (ref null (rtt $t))) (drop (struct.new_default $t (local.get 0))) - ) - ) - "type mismatch" -) diff --git a/proposals/gc/table.wast b/proposals/gc/table.wast index 532c13d..16e35a8 100644 --- a/proposals/gc/table.wast +++ b/proposals/gc/table.wast @@ -15,6 +15,10 @@ (module (table 0 funcref) (table 0 funcref)) (module (table (import "spectest" "table") 0 funcref) (table 0 funcref)) +(module (table 0 funcref (ref.null func))) +(module (table 1 funcref (ref.null func))) +(module (table 1 (ref null func) (ref.null func))) + (assert_invalid (module (elem (i32.const 0))) "unknown table") (assert_invalid (module (elem (i32.const 0) $f) (func $f)) "unknown table") @@ -41,30 +45,76 @@ "i32 constant out of range" ) +(assert_invalid + (module (table 1 (ref null func) (i32.const 0))) + "type mismatch" +) +(assert_invalid + (module (table 1 (ref func) (ref.null extern))) + "type mismatch" +) +(assert_invalid + (module (type $t (func)) (table 1 (ref $t) (ref.null func))) + "type mismatch" +) +(assert_invalid + (module (table 1 (ref func) (ref.null func))) + "type mismatch" +) (assert_invalid (module (table 0 (ref func))) - "non-defaultable element type" + "type mismatch" ) (assert_invalid (module (table 0 (ref extern))) - "non-defaultable element type" + "type mismatch" ) (assert_invalid (module (type $t (func)) (table 0 (ref $t))) - "non-defaultable element type" + "type mismatch" ) + +;; Table initializer + +(module + (type $dummy (func)) + (func $dummy) + + (table $t1 10 funcref) + (table $t2 10 funcref (ref.func $dummy)) + (table $t3 10 (ref $dummy) (ref.func $dummy)) + + (func (export "get1") (result funcref) (table.get $t1 (i32.const 1))) + (func (export "get2") (result funcref) (table.get $t2 (i32.const 4))) + (func (export "get3") (result funcref) (table.get $t3 (i32.const 7))) +) + +(assert_return (invoke "get1") (ref.null)) +(assert_return (invoke "get2") (ref.func)) +(assert_return (invoke "get3") (ref.func)) + + ;; Duplicate table identifiers -(assert_malformed (module quote - "(table $foo 1 funcref)" - "(table $foo 1 funcref)") - "duplicate table") -(assert_malformed (module quote - "(import \"\" \"\" (table $foo 1 funcref))" - "(table $foo 1 funcref)") - "duplicate table") -(assert_malformed (module quote - "(import \"\" \"\" (table $foo 1 funcref))" - "(import \"\" \"\" (table $foo 1 funcref))") - "duplicate table") +(assert_malformed + (module quote + "(table $foo 1 funcref)" + "(table $foo 1 funcref)" + ) + "duplicate table" +) +(assert_malformed + (module quote + "(import \"\" \"\" (table $foo 1 funcref))" + "(table $foo 1 funcref)" + ) + "duplicate table" +) +(assert_malformed + (module quote + "(import \"\" \"\" (table $foo 1 funcref))" + "(import \"\" \"\" (table $foo 1 funcref))" + ) + "duplicate table" +) diff --git a/proposals/gc/type-rec.wast b/proposals/gc/type-rec.wast new file mode 100644 index 0000000..2f6237c --- /dev/null +++ b/proposals/gc/type-rec.wast @@ -0,0 +1,88 @@ +;; Static matching of recursive function types + +(module + (rec (type $f1 (func)) (type (struct))) + (rec (type $f2 (func)) (type (struct))) + (global (ref $f1) (ref.func $f)) + (func $f (type $f2)) +) + +(assert_invalid + (module + (rec (type $f1 (func)) (type (struct))) + (rec (type (struct)) (type $f2 (func))) + (global (ref $f1) (ref.func $f)) + (func $f (type $f2)) + ) + "type mismatch" +) + +(assert_invalid + (module + (rec (type $f1 (func)) (type (struct))) + (rec (type $f2 (func)) (type (struct)) (type (func))) + (global (ref $f1) (ref.func $f)) + (func $f (type $f2)) + ) + "type mismatch" +) + + +;; Link-time matching of recursive function types + +(module $M + (rec (type $f1 (func)) (type (struct))) + (func (export "f") (type $f1)) +) +(register "M" $M) + +(module + (rec (type $f2 (func)) (type (struct))) + (func (import "M" "f") (type $f2)) +) + +(assert_unlinkable + (module + (rec (type (struct)) (type $f2 (func))) + (func (import "M" "f") (type $f2)) + ) + "incompatible import type" +) + +(assert_unlinkable + (module + (rec (type $f2 (func))) + (func (import "M" "f") (type $f2)) + ) + "incompatible import type" +) + + +;; Dynamic matching of recursive function types + +(module + (rec (type $f1 (func)) (type (struct))) + (rec (type $f2 (func)) (type (struct))) + (table funcref (elem $f1)) + (func $f1 (type $f1)) + (func (export "run") (call_indirect (type $f2) (i32.const 0))) +) +(assert_return (invoke "run")) + +(module + (rec (type $f1 (func)) (type (struct))) + (rec (type (struct)) (type $f2 (func))) + (table funcref (elem $f1)) + (func $f1 (type $f1)) + (func (export "run") (call_indirect (type $f2) (i32.const 0))) +) +(assert_trap (invoke "run") "indirect call type mismatch") + +(module + (rec (type $f1 (func)) (type (struct))) + (rec (type $f2 (func))) + (table funcref (elem $f1)) + (func $f1 (type $f1)) + (func (export "run") (call_indirect (type $f2) (i32.const 0))) +) +(assert_trap (invoke "run") "indirect call type mismatch") diff --git a/proposals/gc/type-subtyping.wast b/proposals/gc/type-subtyping.wast index d6d9f9c..4941d5e 100644 --- a/proposals/gc/type-subtyping.wast +++ b/proposals/gc/type-subtyping.wast @@ -28,7 +28,7 @@ (type $f1 (func (param (ref $s')) (result anyref))) (type $f2 (sub $f1 (func (param (ref $s)) (result (ref any))))) (type $f3 (sub $f2 (func (param (ref null $s)) (result (ref $s))))) - (type $f4 (sub $f3 (func (param (ref null data)) (result (ref $s'))))) + (type $f4 (sub $f3 (func (param (ref null struct)) (result (ref $s'))))) ) @@ -125,15 +125,20 @@ (func (export "run") (block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 0))) - (block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 0))) - (block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 1))) - (block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 1))) - (block (result (ref null $t2)) (call_indirect (type $t2) (i32.const 1))) (block (result (ref null $t2)) (call_indirect (type $t2) (i32.const 1))) + (block (result (ref null $t1)) (ref.cast $t1 (table.get (i32.const 0)))) + (block (result (ref null $t1)) (ref.cast $t1 (table.get (i32.const 1)))) + (block (result (ref null $t2)) (ref.cast $t2 (table.get (i32.const 1)))) + (br 0) + ) + + (func (export "fail") + (block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 1))) (br 0) ) ) (assert_return (invoke "run")) +(assert_trap (invoke "fail") "indirect call") ;; Invalid subtyping definitions diff --git a/proposals/gc/unreached-invalid.wast b/proposals/gc/unreached-invalid.wast index 849fee6..1dfcf91 100644 --- a/proposals/gc/unreached-invalid.wast +++ b/proposals/gc/unreached-invalid.wast @@ -758,3 +758,25 @@ )) "type mismatch" ) + + +(assert_invalid + (module + (type $t (func (param i32) (result i64))) + (func (result i32) + (unreachable) + (call_ref $t) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type $t (func (param i32) (result i32 i32))) + (func (result i32) + (unreachable) + (call_ref $t) + ) + ) + "type mismatch" +) diff --git a/proposals/gc/unreached-valid.wast b/proposals/gc/unreached-valid.wast new file mode 100644 index 0000000..f3feb0f --- /dev/null +++ b/proposals/gc/unreached-valid.wast @@ -0,0 +1,108 @@ +(module + + ;; Check that both sides of the select are evaluated + (func (export "select-trap-left") (param $cond i32) (result i32) + (select (unreachable) (i32.const 0) (local.get $cond)) + ) + (func (export "select-trap-right") (param $cond i32) (result i32) + (select (i32.const 0) (unreachable) (local.get $cond)) + ) + + (func (export "select-unreached") + (unreachable) (select) + (unreachable) (i32.const 0) (select) + (unreachable) (i32.const 0) (i32.const 0) (select) + (unreachable) (i32.const 0) (i32.const 0) (i32.const 0) (select) + (unreachable) (f32.const 0) (i32.const 0) (select) + (unreachable) + ) + + (func (export "select-unreached-result1") (result i32) + (unreachable) (i32.add (select)) + ) + + (func (export "select-unreached-result2") (result i64) + (unreachable) (i64.add (select (i64.const 0) (i32.const 0))) + ) + + (func (export "select-unreached-num") + (unreachable) + (select) + (i32.eqz) + (drop) + ) + (func (export "select-unreached-ref") + (unreachable) + (select) + (ref.is_null) + (drop) + ) + + (type $t (func (param i32) (result i32))) + (func (export "call_ref-unreached") (result i32) + (unreachable) + (call_ref $t) + ) +) + +(assert_trap (invoke "select-trap-left" (i32.const 1)) "unreachable") +(assert_trap (invoke "select-trap-left" (i32.const 0)) "unreachable") +(assert_trap (invoke "select-trap-right" (i32.const 1)) "unreachable") +(assert_trap (invoke "select-trap-right" (i32.const 0)) "unreachable") + +(assert_trap (invoke "select-unreached-result1") "unreachable") +(assert_trap (invoke "select-unreached-result2") "unreachable") +(assert_trap (invoke "select-unreached-num") "unreachable") +(assert_trap (invoke "select-unreached-ref") "unreachable") + +(assert_trap (invoke "call_ref-unreached") "unreachable") + + +;; Validation after unreachable + +(module + (func (export "meet-bottom") + (block (result f64) + (block (result f32) + (unreachable) + (br_table 0 1 1 (i32.const 1)) + ) + (drop) + (f64.const 0) + ) + (drop) + ) +) + +(assert_trap (invoke "meet-bottom") "unreachable") + + +;; Bottom heap type + +(module + (func (result (ref func)) + (unreachable) + (ref.as_non_null) + ) + (func (result (ref extern)) + (unreachable) + (ref.as_non_null) + ) + + (func (result (ref func)) + (block (result funcref) + (unreachable) + (br_on_null 0) + (return) + ) + (unreachable) + ) + (func (result (ref extern)) + (block (result externref) + (unreachable) + (br_on_null 0) + (return) + ) + (unreachable) + ) +) diff --git a/proposals/multi-memory/imports.wast b/proposals/multi-memory/imports.wast index a1609c8..94c1af5 100644 --- a/proposals/multi-memory/imports.wast +++ b/proposals/multi-memory/imports.wast @@ -30,11 +30,9 @@ (type $func_f64 (func (param f64))) (import "spectest" "print_i32" (func (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (func (import "spectest" "print_i64") (param i64)) + (func (import "spectest" "print_i64") (param i64)) (import "spectest" "print_i32" (func $print_i32 (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "print_i64" (func $print_i64 (param i64))) + (import "spectest" "print_i64" (func $print_i64 (param i64))) (import "spectest" "print_f32" (func $print_f32 (param f32))) (import "spectest" "print_f64" (func $print_f64 (param f64))) (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) @@ -72,14 +70,12 @@ (func (export "print64") (param $i i64) (local $x f64) (local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i)))) - ;; JavaScript can't handle i64 yet. - ;; (call 1 (local.get $i)) + (call 1 (local.get $i)) (call $print_f64_f64 (f64.add (local.get $x) (f64.const 1)) (f64.const 53) ) - ;; JavaScript can't handle i64 yet. - ;; (call $print_i64 (local.get $i)) + (call $print_i64 (local.get $i)) (call $print_f64 (local.get $x)) (call $print_f64-2 (local.get $x)) (call_indirect (type $func_f64) (local.get $x) (i32.const 1)) @@ -234,8 +230,7 @@ (import "spectest" "global_i32" (global $x i32)) (global $y (import "spectest" "global_i32") i32) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "global_i64" (global i64)) + (import "spectest" "global_i64" (global i64)) (import "spectest" "global_f32" (global f32)) (import "spectest" "global_f64" (global f64)) diff --git a/proposals/relaxed-simd/relaxed_dot_product.wast b/proposals/relaxed-simd/relaxed_dot_product.wast new file mode 100644 index 0000000..245b1db --- /dev/null +++ b/proposals/relaxed-simd/relaxed_dot_product.wast @@ -0,0 +1,43 @@ +;; Tests for relaxed dot products. + +(module + (func (export "i16x8.dot_i8x16_i7x16_s") (param v128 v128) (result v128) (i16x8.dot_i8x16_i7x16_s (local.get 0) (local.get 1))) + (func (export "i32x4.dot_i8x16_i7x16_add_s") (param v128 v128 v128) (result v128) (i32x4.dot_i8x16_i7x16_add_s (local.get 0) (local.get 1) (local.get 2))) + (func (export "f32x4.relaxed_dot_bf16x8_add_f32x4") (param v128 v128 v128) (result v128) (f32x4.relaxed_dot_bf16x8_add_f32x4 (local.get 0) (local.get 1) (local.get 2))) +) + +;; Simple values to ensure things are functional. +(assert_return (invoke "i16x8.dot_i8x16_i7x16_s" + (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) + (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)) + (v128.const i16x8 1 13 41 85 145 221 313 421)) + +;; Test max and min i8 values; +(assert_return (invoke "i16x8.dot_i8x16_i7x16_s" + (v128.const i8x16 -128 -128 127 127 0 0 0 0 0 0 0 0 0 0 0 0) + (v128.const i8x16 127 127 127 127 0 0 0 0 0 0 0 0 0 0 0 0)) + (v128.const i16x8 -32512 32258 0 0 0 0 0 0)) + +;; Simple values to ensure things are functional. +(assert_return (invoke "i32x4.dot_i8x16_i7x16_add_s" + (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) + (v128.const i8x16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) + (v128.const i32x4 0 1 2 3)) + ;; intermediate result is [14, 126, 366, 734] + (v128.const f32x4 14 127 368 737)) + +;; Test max and min i8 values; +(assert_return (invoke "i32x4.dot_i8x16_i7x16_add_s" + (v128.const i8x16 -128 -128 -128 -128 127 127 127 127 0 0 0 0 0 0 0 0) + (v128.const i8x16 127 127 127 127 127 127 127 127 0 0 0 0 0 0 0 0) + (v128.const i32x4 1 2 3 4)) + ;; intermediate result is [-65024, 64516, 0, 0] + (v128.const f32x4 -65023 64518 3 4)) + +;; Simple values to ensure things are functional. +(assert_return (invoke "f32x4.relaxed_dot_bf16x8_add_f32x4" + (v128.const i16x8 0x0000 0x3f80 0x4000 0x4040 0x4080 0x40a0 0x40c0 0x40e0) ;; [0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f] + (v128.const i16x8 0x0000 0x3f80 0x4000 0x4040 0x4080 0x40a0 0x40c0 0x40e0) + (v128.const f32x4 0 1 2 3)) + ;; intermediate result is [1, 13, 41, 85] + (v128.const f32x4 1 14 43 88)) diff --git a/proposals/relaxed-simd/relaxed_fma_fms.wast b/proposals/relaxed-simd/relaxed_madd_nmadd.wast similarity index 79% rename from proposals/relaxed-simd/relaxed_fma_fms.wast rename to proposals/relaxed-simd/relaxed_madd_nmadd.wast index d895d88..d212d53 100644 --- a/proposals/relaxed-simd/relaxed_fma_fms.wast +++ b/proposals/relaxed-simd/relaxed_madd_nmadd.wast @@ -1,10 +1,10 @@ -;; Tests for f32x4.relaxed_fma, f32x4.relaxed_fms, f64x2.relaxed_fma, and f64x2.relaxed_fms. +;; Tests for f32x4.relaxed_madd, f32x4.relaxed_nmadd, f64x2.relaxed_madd, and f64x2.relaxed_nmadd. (module - (func (export "f32x4.relaxed_fma") (param v128 v128 v128) (result v128) (f32x4.relaxed_fma (local.get 0) (local.get 1) (local.get 2))) - (func (export "f32x4.relaxed_fms") (param v128 v128 v128) (result v128) (f32x4.relaxed_fms (local.get 0) (local.get 1) (local.get 2))) - (func (export "f64x2.relaxed_fms") (param v128 v128 v128) (result v128) (f64x2.relaxed_fms (local.get 0) (local.get 1) (local.get 2))) - (func (export "f64x2.relaxed_fma") (param v128 v128 v128) (result v128) (f64x2.relaxed_fma (local.get 0) (local.get 1) (local.get 2))) + (func (export "f32x4.relaxed_madd") (param v128 v128 v128) (result v128) (f32x4.relaxed_madd (local.get 0) (local.get 1) (local.get 2))) + (func (export "f32x4.relaxed_nmadd") (param v128 v128 v128) (result v128) (f32x4.relaxed_nmadd (local.get 0) (local.get 1) (local.get 2))) + (func (export "f64x2.relaxed_nmadd") (param v128 v128 v128) (result v128) (f64x2.relaxed_nmadd (local.get 0) (local.get 1) (local.get 2))) + (func (export "f64x2.relaxed_madd") (param v128 v128 v128) (result v128) (f64x2.relaxed_madd (local.get 0) (local.get 1) (local.get 2))) ) @@ -13,7 +13,7 @@ ;; FLT_MAX (if fma) ;; 0 (if no fma) ;; from https://www.vinc17.net/software/fma-tests.c -(assert_return (invoke "f32x4.relaxed_fma" +(assert_return (invoke "f32x4.relaxed_madd" (v128.const f32x4 0x1.fffffep+127 0x1.fffffep+127 0x1.fffffep+127 0x1.fffffep+127 ) (v128.const f32x4 2.0 2.0 2.0 2.0) (v128.const f32x4 -0x1.fffffep+127 -0x1.fffffep+127 -0x1.fffffep+127 -0x1.fffffep+127)) @@ -29,13 +29,13 @@ ;; x.y+z = 0 (2 roundings) ;; fma(x, y, z) = (0x1p-37) 2^-37 ;; from https://accurate-algorithms.readthedocs.io/en/latest/ch09appendix.html#test-system-information -(assert_return (invoke "f32x4.relaxed_fma" +(assert_return (invoke "f32x4.relaxed_madd" (v128.const f32x4 0x1.000004p+0 0x1.000004p+0 0x1.000004p+0 0x1.000004p+0) (v128.const f32x4 0x1.0002p+0 0x1.0002p+0 0x1.0002p+0 0x1.0002p+0) (v128.const f32x4 -0x1.000204p+0 -0x1.000204p+0 -0x1.000204p+0 -0x1.000204p+0)) (either (v128.const f32x4 0x1p-37 0x1p-37 0x1p-37 0x1p-37) (v128.const f32x4 0 0 0 0))) -(assert_return (invoke "f32x4.relaxed_fms" +(assert_return (invoke "f32x4.relaxed_nmadd" (v128.const f32x4 0x1.000004p+0 0x1.000004p+0 0x1.000004p+0 0x1.000004p+0) (v128.const f32x4 0x1.0002p+0 0x1.0002p+0 0x1.0002p+0 0x1.0002p+0) (v128.const f32x4 0x1.000204p+0 0x1.000204p+0 0x1.000204p+0 0x1.000204p+0)) @@ -48,7 +48,7 @@ ;; 0 (if no fma) ;; form https://www.vinc17.net/software/fma-tests.c ;; from https://www.vinc17.net/software/fma-tests.c -(assert_return (invoke "f64x2.relaxed_fma" +(assert_return (invoke "f64x2.relaxed_madd" (v128.const f64x2 0x1.fffffffffffffp+1023 0x1.fffffffffffffp+1023) (v128.const f64x2 2.0 2.0) (v128.const f64x2 -0x1.fffffffffffffp+1023 -0x1.fffffffffffffp+1023)) @@ -64,13 +64,13 @@ ;; x.y+z = 0 (2 roundings) ;; fma(x, y, z) = 0x1p-53 ;; from https://accurate-algorithms.readthedocs.io/en/latest/ch09appendix.html#test-system-information -(assert_return (invoke "f64x2.relaxed_fma" +(assert_return (invoke "f64x2.relaxed_madd" (v128.const f64x2 0x1.00000004p+0 0x1.00000004p+0) (v128.const f64x2 0x1.000002p+0 0x1.000002p+0) (v128.const f64x2 -0x1.00000204p+0 -0x1.00000204p+0)) (either (v128.const f64x2 0x1p-53 0x1p-53) (v128.const f64x2 0 0))) -(assert_return (invoke "f64x2.relaxed_fms" +(assert_return (invoke "f64x2.relaxed_nmadd" (v128.const f64x2 0x1.00000004p+0 0x1.00000004p+0) (v128.const f64x2 0x1.000002p+0 0x1.000002p+0) (v128.const f64x2 0x1.00000204p+0 0x1.00000204p+0)) diff --git a/simd_lane.wast b/simd_lane.wast index 9d4b5fd..9b66f53 100644 --- a/simd_lane.wast +++ b/simd_lane.wast @@ -447,8 +447,8 @@ (assert_invalid (module (func (result v128) (i16x8.replace_lane 255 (v128.const i16x8 0 0 0 0 0 0 0 0) (i32.const 1)))) "invalid lane index") (assert_invalid (module (func (result v128) (i32x4.replace_lane 4 (v128.const i32x4 0 0 0 0) (i32.const 1)))) "invalid lane index") (assert_invalid (module (func (result v128) (i32x4.replace_lane 255 (v128.const i32x4 0 0 0 0) (i32.const 1)))) "invalid lane index") -(assert_invalid (module (func (result v128) (f32x4.replace_lane 4 (v128.const f32x4 0 0 0 0) (i32.const 1)))) "invalid lane index") -(assert_invalid (module (func (result v128) (f32x4.replace_lane 255 (v128.const f32x4 0 0 0 0) (i32.const 1)))) "invalid lane index") +(assert_invalid (module (func (result v128) (f32x4.replace_lane 4 (v128.const f32x4 0 0 0 0) (f32.const 1)))) "invalid lane index") +(assert_invalid (module (func (result v128) (f32x4.replace_lane 255 (v128.const f32x4 0 0 0 0) (f32.const 1)))) "invalid lane index") (assert_invalid (module (func (result i64) (i64x2.extract_lane 2 (v128.const i64x2 0 0)))) "invalid lane index") (assert_invalid (module (func (result i64) (i64x2.extract_lane 255 (v128.const i64x2 0 0)))) "invalid lane index") (assert_invalid (module (func (result f64) (f64x2.extract_lane 2 (v128.const f64x2 0 0)))) "invalid lane index") @@ -466,7 +466,7 @@ (assert_invalid (module (func (result i32) (f32x4.extract_lane 4 (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)))) "invalid lane index") (assert_invalid (module (func (result v128) (i16x8.replace_lane 8 (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (i32.const 1)))) "invalid lane index") (assert_invalid (module (func (result v128) (i32x4.replace_lane 4 (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (i32.const 1)))) "invalid lane index") -(assert_invalid (module (func (result v128) (f32x4.replace_lane 4 (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (i32.const 1)))) "invalid lane index") +(assert_invalid (module (func (result v128) (f32x4.replace_lane 4 (v128.const i8x16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (f32.const 1)))) "invalid lane index") (assert_invalid (module (func (result i64) (i64x2.extract_lane 2 (v128.const i64x2 0 0)))) "invalid lane index") (assert_invalid (module (func (result f64) (f64x2.extract_lane 2 (v128.const f64x2 0 0)))) "invalid lane index") (assert_invalid (module (func (result v128) (i64x2.replace_lane 2 (v128.const i64x2 0 0) (i64.const 1)))) "invalid lane index")