diff --git a/binary-leb128.wast b/binary-leb128.wast index cd39a5d..8503c9a 100644 --- a/binary-leb128.wast +++ b/binary-leb128.wast @@ -852,7 +852,7 @@ "\41\00" ;; i32.const 0 "\41\03" ;; i32.const 3 "\36" ;; i32.store - "\03" ;; alignment 2 + "\02" ;; alignment 2 "\82\80\80\80\10" ;; offset 2 with unused bits set "\0b" ;; end ) diff --git a/binary.wast b/binary.wast index 8b5bcfc..fd188d7 100644 --- a/binary.wast +++ b/binary.wast @@ -52,6 +52,20 @@ (assert_malformed (module binary "\00asm" "\01\00\00\00" "\ff\00\01\00") "malformed section id") +;; Type section with signed LEB128 encoded type +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01" ;; Type section id + "\05" ;; Type section length + "\01" ;; Types vector length + "\e0\7f" ;; Malformed functype, -0x20 in signed LEB128 encoding + "\00\00" + ) + "integer representation too long" +) + + ;; call_indirect reserved byte equal to zero. (assert_malformed (module binary @@ -773,8 +787,23 @@ "\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given) "\00\41\00\0b\01\00" ;; elem 0 ;; "\00\41\00\0b\01\00" ;; elem 1 (missed) - "\0a\04\01" ;; code section - "\02\00\0b" ;; function body + ) + "unexpected end" +) + +;; 2 elem segment declared, 1.5 given +(assert_malformed + (module binary + "\00asm" "\01\00\00\00" + "\01\04\01" ;; type section + "\60\00\00" ;; type 0 + "\03\02\01\00" ;; func section + "\04\04\01" ;; table section + "\70\00\01" ;; table 0 + "\09\07\02" ;; elem with inconsistent segment count (2 declared, 1 given) + "\00\41\00\0b\01\00" ;; elem 0 + "\00\41\00" ;; elem 1 (partial) + ;; "\0b\01\00" ;; elem 1 (missing part) ) "unexpected end" ) diff --git a/data.wast b/data.wast index 7d69454..d65abf3 100644 --- a/data.wast +++ b/data.wast @@ -286,6 +286,69 @@ "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\06\01" ;; data section + "\01\41\00\0b" ;; data segment 0 for memory 1 + "\00" ;; empty vec(byte) + ) + "unknown memory 1" +) + +;; Data segment with memory index 1 (no memory section) +(assert_invalid + (module binary + "\00asm" "\01\00\00\00" + "\0b\06\01" ;; data section + "\01\41\00\0b" ;; 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\44\01" ;; data section + "\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\44\01" ;; data section + "\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 diff --git a/proposals/simd/simd_i32x4_dot_i16x8.wast b/proposals/simd/simd_i32x4_dot_i16x8.wast new file mode 100644 index 0000000..b41de74 --- /dev/null +++ b/proposals/simd/simd_i32x4_dot_i16x8.wast @@ -0,0 +1,110 @@ +;; Tests for i32x4 arithmetic operations on major boundary values and all special values. + + +(module + (func (export "i32x4.dot_i16x8_s") (param v128 v128) (result v128) (i32x4.dot_i16x8_s (local.get 0) (local.get 1))) +) + + +;; i32x4.dot_i16x8_s +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 0 0 0 0 0 0 0 0) + (v128.const i16x8 0 0 0 0 0 0 0 0)) + (v128.const i32x4 0 0 0 0)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 0 0 0 0 0 0 0 0) + (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 0 0 0 0)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 1 1 1 1 1 1 1 1) + (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 2 2 2 2)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 0 0 0 0 0 0 0 0) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 0 0 0 0)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 1 1 1 1 1 1 1 1) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 -2 -2 -2 -2)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 2 2 2 2)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 16383 16383 16383 16383 16383 16383 16383 16383) + (v128.const i16x8 16384 16384 16384 16384 16384 16384 16384 16384)) + (v128.const i32x4 536838144 536838144 536838144 536838144)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 16384 16384 16384 16384 16384 16384 16384 16384) + (v128.const i16x8 16384 16384 16384 16384 16384 16384 16384 16384)) + (v128.const i32x4 536870912 536870912 536870912 536870912)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -16383 -16383 -16383 -16383 -16383 -16383 -16383 -16383) + (v128.const i16x8 -16384 -16384 -16384 -16384 -16384 -16384 -16384 -16384)) + (v128.const i32x4 536838144 536838144 536838144 536838144)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -16384 -16384 -16384 -16384 -16384 -16384 -16384 -16384) + (v128.const i16x8 -16384 -16384 -16384 -16384 -16384 -16384 -16384 -16384)) + (v128.const i32x4 536870912 536870912 536870912 536870912)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -16385 -16385 -16385 -16385 -16385 -16385 -16385 -16385) + (v128.const i16x8 -16384 -16384 -16384 -16384 -16384 -16384 -16384 -16384)) + (v128.const i32x4 536903680 536903680 536903680 536903680)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 32765 32765 32765 32765 32765 32765 32765 32765) + (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 65530 65530 65530 65530)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 32766 32766 32766 32766 32766 32766 32766 32766) + (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 65532 65532 65532 65532)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 32768 32768 32768 32768 32768 32768 32768 32768) + (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 -65536 -65536 -65536 -65536)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -32766 -32766 -32766 -32766 -32766 -32766 -32766 -32766) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 65532 65532 65532 65532)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -32767 -32767 -32767 -32767 -32767 -32767 -32767 -32767) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 65534 65534 65534 65534)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 65536 65536 65536 65536)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 32767 32767 32767 32767 32767 32767 32767 32767) + (v128.const i16x8 32767 32767 32767 32767 32767 32767 32767 32767)) + (v128.const i32x4 2147352578 2147352578 2147352578 2147352578)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768) + (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768)) + (v128.const i32x4 2147483648 2147483648 2147483648 2147483648)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768) + (v128.const i16x8 -32767 -32767 -32767 -32767 -32767 -32767 -32767 -32767)) + (v128.const i32x4 2147418112 2147418112 2147418112 2147418112)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535) + (v128.const i16x8 0 0 0 0 0 0 0 0)) + (v128.const i32x4 0 0 0 0)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535) + (v128.const i16x8 1 1 1 1 1 1 1 1)) + (v128.const i32x4 -2 -2 -2 -2)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535) + (v128.const i16x8 -1 -1 -1 -1 -1 -1 -1 -1)) + (v128.const i32x4 2 2 2 2)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535) + (v128.const i16x8 32767 32767 32767 32767 32767 32767 32767 32767)) + (v128.const i32x4 -65534 -65534 -65534 -65534)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535) + (v128.const i16x8 -32768 -32768 -32768 -32768 -32768 -32768 -32768 -32768)) + (v128.const i32x4 65536 65536 65536 65536)) +(assert_return (invoke "i32x4.dot_i16x8_s" (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535) + (v128.const i16x8 65535 65535 65535 65535 65535 65535 65535 65535)) + (v128.const i32x4 2 2 2 2)) + +;; type check +(assert_invalid (module (func (result v128) (i32x4.dot_i16x8_s (i32.const 0) (f32.const 0.0)))) "type mismatch") + +;; Test operation with empty argument + +(assert_invalid + (module + (func $i32x4.dot_i16x8_s-1st-arg-empty (result v128) + (i32x4.dot_i16x8_s (v128.const i32x4 0 0 0 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (func $i32x4.dot_i16x8_s-arg-empty (result v128) + (i32x4.dot_i16x8_s) + ) + ) + "type mismatch" +) + diff --git a/proposals/simd/simd_load_zero.wast b/proposals/simd/simd_load_zero.wast new file mode 100644 index 0000000..6276a68 --- /dev/null +++ b/proposals/simd/simd_load_zero.wast @@ -0,0 +1,154 @@ +;; Load and Zero extend test cases + +(module + (memory 1) + (data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\80\81\82\83\84\85\86\87\88\89") + (data (i32.const 65520) "\0A\0B\0C\0D\0E\0F\80\81\82\83\84\85\86\87\88\89") + + (func (export "v128.load32_zero") (param $0 i32) (result v128) + (v128.load32_zero (local.get $0)) + ) + (func (export "v128.load64_zero") (param $0 i32) (result v128) + (v128.load64_zero (local.get $0)) + ) + + ;; load by a constant amount + (func (export "v128.load32_zero_const0") (result v128) + (v128.load32_zero (i32.const 0)) + ) + (func (export "v128.load64_zero_const8") (result v128) + (v128.load64_zero (i32.const 8)) + ) + + ;; load data with different offset/align arguments + ;; i16x8 + (func (export "v128.load32_zero_offset0") (param $0 i32) (result v128) + (v128.load32_zero offset=0 (local.get $0)) + ) + (func (export "v128.load32_zero_align1") (param $0 i32) (result v128) + (v128.load32_zero align=1 (local.get $0)) + ) + (func (export "v128.load32_zero_offset0_align1") (param $0 i32) (result v128) + (v128.load32_zero offset=0 align=1 (local.get $0)) + ) + (func (export "v128.load32_zero_offset1_align1") (param $0 i32) (result v128) + (v128.load32_zero offset=1 align=1 (local.get $0)) + ) + (func (export "v128.load32_zero_offset10_align4") (param $0 i32) (result v128) + (v128.load32_zero offset=10 align=4 (local.get $0)) + ) + (func (export "v128.load64_zero_offset0") (param $0 i32) (result v128) + (v128.load64_zero offset=0 (local.get $0)) + ) + (func (export "v128.load64_zero_align1") (param $0 i32) (result v128) + (v128.load64_zero align=1 (local.get $0)) + ) + (func (export "v128.load64_zero_offset0_align1") (param $0 i32) (result v128) + (v128.load64_zero offset=0 align=1 (local.get $0)) + ) + (func (export "v128.load64_zero_offset1_align1") (param $0 i32) (result v128) + (v128.load64_zero offset=1 align=1 (local.get $0)) + ) + (func (export "v128.load64_zero_offset10_align4") (param $0 i32) (result v128) + (v128.load64_zero offset=10 align=4 (local.get $0)) + ) + (func (export "v128.load64_zero_offset20_align8") (param $0 i32) (result v128) + (v128.load64_zero offset=20 align=8 (local.get $0)) + ) +) + + +;; normal +(assert_return (invoke "v128.load32_zero" (i32.const 0)) (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load64_zero" (i32.const 0)) (v128.const i64x2 0x0706050403020100 0x0000000000000000)) +(assert_return (invoke "v128.load32_zero" (i32.const 10)) (v128.const i32x4 0x0D0C0B0A 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load64_zero" (i32.const 10)) (v128.const i64x2 0x81800F0E0D0C0B0A 0x0000000000000000)) +(assert_return (invoke "v128.load32_zero" (i32.const 20)) (v128.const i32x4 0x87868584 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load64_zero" (i32.const 20)) (v128.const i64x2 0x0000898887868584 0x0000000000000000)) + +;; load by a constant amount +(assert_return (invoke "v128.load32_zero_const0") (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load64_zero_const8") (v128.const i64x2 0x0F0E0D0C0B0A0908 0x0000000000000000)) + +;; load data with different offset/align arguments +;; load32_zero +(assert_return (invoke "v128.load32_zero_offset0" (i32.const 0)) (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load32_zero_align1" (i32.const 1)) (v128.const i32x4 0x04030201 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load32_zero_offset0_align1" (i32.const 2)) (v128.const i32x4 0x05040302 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load32_zero_offset10_align4" (i32.const 3)) (v128.const i32x4 0x800F0E0D 0x00000000 0x00000000 0x00000000)) + +;; load64_zero +(assert_return (invoke "v128.load64_zero_offset0" (i32.const 0)) (v128.const i64x2 0x0706050403020100 0x0000000000000000)) +(assert_return (invoke "v128.load64_zero_align1" (i32.const 1)) (v128.const i64x2 0x0807060504030201 0x0000000000000000)) +(assert_return (invoke "v128.load64_zero_offset0_align1" (i32.const 2)) (v128.const i64x2 0x0908070605040302 0x0000000000000000)) +(assert_return (invoke "v128.load64_zero_offset10_align4" (i32.const 3)) (v128.const i64x2 0x84838281800F0E0D 0x0000000000000000)) +(assert_return (invoke "v128.load64_zero_offset20_align8" (i32.const 4)) (v128.const i64x2 0x0000000000008988 0x0000000000000000)) + +;; out of bounds memory access +(assert_trap (invoke "v128.load32_zero" (i32.const -1)) "out of bounds memory access") +(assert_trap (invoke "v128.load64_zero" (i32.const -1)) "out of bounds memory access") + +(assert_trap (invoke "v128.load32_zero_offset1_align1" (i32.const -1)) "out of bounds memory access") +(assert_trap (invoke "v128.load64_zero_offset1_align1" (i32.const -1)) "out of bounds memory access") + +;; type check +(assert_invalid (module (memory 0) (func (result v128) (v128.load32_zero (f32.const 0)))) "type mismatch") +(assert_invalid (module (memory 0) (func (result v128) (v128.load64_zero (f32.const 0)))) "type mismatch") + +;; Test operation with empty argument + +(assert_invalid + (module (memory 0) + (func $v128.load32_zero-arg-empty (result v128) + (v128.load32_zero) + ) + ) + "type mismatch" +) +(assert_invalid + (module (memory 0) + (func $v128.load64_zero-arg-empty (result v128) + (v128.load64_zero) + ) + ) + "type mismatch" +) + +;; Unknown operator + +(assert_malformed (module quote "(memory 1) (func (drop (i16x8.load16x4_s (i32.const 0))))") "unknown operator") +(assert_malformed (module quote "(memory 1) (func (drop (i16x8.load16x4_u (i32.const 0))))") "unknown operator") +(assert_malformed (module quote "(memory 1) (func (drop (i32x4.load32x2_s (i32.const 0))))") "unknown operator") +(assert_malformed (module quote "(memory 1) (func (drop (i32x4.load32x2_u (i32.const 0))))") "unknown operator") +(assert_malformed (module quote "(memory 1) (func (drop (i64x2.load64x1_s (i32.const 0))))") "unknown operator") +(assert_malformed (module quote "(memory 1) (func (drop (i64x2.load64x1_u (i32.const 0))))") "unknown operator") + +;; combination +(module + (memory 1) + (data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\80\81\82\83\84\85\86\87\88\89") + (func (export "v128.load32_zero-in-block") (result v128) + (block (result v128) (block (result v128) (v128.load32_zero (i32.const 0)))) + ) + (func (export "v128.load64_zero-in-block") (result v128) + (block (result v128) (block (result v128) (v128.load64_zero (i32.const 1)))) + ) + (func (export "v128.load32_zero-as-br-value") (result v128) + (block (result v128) (br 0 (v128.load32_zero (i32.const 6)))) + ) + (func (export "v128.load64_zero-as-br-value") (result v128) + (block (result v128) (br 0 (v128.load64_zero (i32.const 7)))) + ) + (func (export "v128.load32_zero-extract_lane_s-operand") (result i32) + (i32x4.extract_lane 0 (v128.load32_zero (i32.const 12))) + ) + (func (export "v128.load64_zero-extract_lane_s-operand") (result i64) + (i64x2.extract_lane 0 (v128.load64_zero (i32.const 13))) + ) +) +(assert_return (invoke "v128.load32_zero-in-block") (v128.const i32x4 0x03020100 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load64_zero-in-block") (v128.const i64x2 0x0807060504030201 0x0000000000000000)) +(assert_return (invoke "v128.load32_zero-as-br-value") (v128.const i32x4 0x09080706 0x00000000 0x00000000 0x00000000)) +(assert_return (invoke "v128.load64_zero-as-br-value") (v128.const i64x2 0x0E0D0C0B0A090807 0x0000000000000000)) +(assert_return (invoke "v128.load32_zero-extract_lane_s-operand") (i32.const 0x0F0E0D0C)) +(assert_return (invoke "v128.load64_zero-extract_lane_s-operand") (i64.const 0x84838281800F0E0D))