diff --git a/ml-proto/TestingTodo.md b/ml-proto/TestingTodo.md index fa3630cdbf..ef6abee012 100644 --- a/ml-proto/TestingTodo.md +++ b/ml-proto/TestingTodo.md @@ -11,9 +11,9 @@ Misc semantics: - test that too-big `grow_memory` fails appropriately - test that too-big linear memory initial allocation fails - test that function addresses are monotonic indices, and not actual addresses. - - test that non-pagesize `grow_memory` fails + - ~~test that non-pagesize `grow_memory` fails~~ - test that non-pagesize initial linear memory allocation fails - - test that one can clobber the entire contents of the linear memory without corrupting: call stack, global variables, local variables, program execution. + - test that one can clobber the entire contents of the linear memory without corrupting: call stack, local variables, program execution. Operator semantics: - test that promote/demote, sext/trunc, zext/trunc is bit-preserving if not NaN @@ -24,7 +24,10 @@ Operator semantics: - ~~test that `page_size` returns a power of 2~~ - ~~test that arithmetic operands are evaluated left-to-right~~ - ~~test that call and store operands are evaluated left-to-right too~~ - - test that call and argument operands of call_indirect are evaluated left-to-right, too + - ~~test that call and argument operands of call_indirect are evaluated left-to-right, too~~ + - ~~test that select arguments are evaluated left-to-right, too~~ + - test that br_if arguments are evaluated left-to-right, too + - test that tableswitch arguments are evaluated left-to-right, too - ~~test that add/sub/mul/wrap/wrapping-store silently wrap on overflow~~ - ~~test that sdiv/udiv/srem/urem trap on divide-by-zero~~ - ~~test that sdiv traps on overflow~~ @@ -33,7 +36,7 @@ Operator semantics: - ~~test that unsigned operations are properly unsigned~~ - ~~test that signed integer div rounds toward zero~~ - ~~test that signed integer mod has the sign of the dividend~~ - - test that select preserves all NaN bits + - ~~test that select preserves all NaN bits~~ Floating point semantics: - ~~test for round-to-nearest rounding~~ diff --git a/ml-proto/test/fac.wast b/ml-proto/test/fac.wast index 41bcc203aa..4d19074d12 100644 --- a/ml-proto/test/fac.wast +++ b/ml-proto/test/fac.wast @@ -23,20 +23,18 @@ (local i64 i64) (set_local 1 (get_local 0)) (set_local 2 (i64.const 1)) - (block - (loop - (if_else - (i64.eq (get_local 1) (i64.const 0)) - (br 1) - (block - (set_local 2 (i64.mul (get_local 1) (get_local 2))) - (set_local 1 (i64.sub (get_local 1) (i64.const 1))) - ) + (loop + (if_else + (i64.eq (get_local 1) (i64.const 0)) + (br 1) + (block + (set_local 2 (i64.mul (get_local 1) (get_local 2))) + (set_local 1 (i64.sub (get_local 1) (i64.const 1))) ) - (br 0) ) + (br 0) ) - (return (get_local 2)) + (get_local 2) ) ;; Iterative factorial named @@ -45,30 +43,45 @@ (local $res i64) (set_local $i (get_local $n)) (set_local $res (i64.const 1)) - (block $done - (loop $loop - (if_else - (i64.eq (get_local $i) (i64.const 0)) - (br $done) - (block - (set_local $res (i64.mul (get_local $i) (get_local $res))) - (set_local $i (i64.sub (get_local $i) (i64.const 1))) - ) + (loop $done $loop + (if_else + (i64.eq (get_local $i) (i64.const 0)) + (br $done) + (block + (set_local $res (i64.mul (get_local $i) (get_local $res))) + (set_local $i (i64.sub (get_local $i) (i64.const 1))) ) - (br $loop) + ) + (br $loop) + ) + (get_local $res) + ) + + ;; More-realistically optimized factorial. + (func $fac-opt (param i64) (result i64) + (local i64) + (set_local 1 (i64.const 1)) + (block + (br_if (i64.lt_s (get_local 0) (i64.const 2)) 0) + (loop + (set_local 1 (i64.mul (get_local 1) (get_local 0))) + (set_local 0 (i64.add (get_local 0) (i64.const -1))) + (br_if (i64.gt_s (get_local 0) (i64.const 1)) 0) ) ) - (return (get_local $res)) + (get_local 1) ) (export "fac-rec" 0) (export "fac-iter" 2) (export "fac-rec-named" $fac-rec) (export "fac-iter-named" $fac-iter) + (export "fac-opt" $fac-opt) ) (assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-iter" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-rec-named" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-iter-named" (i64.const 25)) (i64.const 7034535277573963776)) +(assert_return (invoke "fac-opt" (i64.const 25)) (i64.const 7034535277573963776)) (assert_trap (invoke "fac-rec" (i64.const 1073741824)) "call stack exhausted") diff --git a/ml-proto/test/int_literals.wast b/ml-proto/test/int_literals.wast index e8d1c09944..a60adb439d 100644 --- a/ml-proto/test/int_literals.wast +++ b/ml-proto/test/int_literals.wast @@ -7,6 +7,7 @@ (func $i32.alt_smin (result i32) (return (i32.const 0x80000000))) (func $i32.inc_smin (result i32) (return (i32.add (i32.const -0x80000000) (i32.const 1)))) (func $i32.neg_zero (result i32) (return (i32.const -0x0))) + (func $i32.not_octal (result i32) (return (i32.const 010))) (func $i64.test (result i64) (return (i64.const 0x0CABBA6E0ba66a6e))) (func $i64.umax (result i64) (return (i64.const 0xffffffffffffffff))) @@ -16,6 +17,7 @@ (func $i64.alt_smin (result i64) (return (i64.const 0x8000000000000000))) (func $i64.inc_smin (result i64) (return (i64.add (i64.const -0x8000000000000000) (i64.const 1)))) (func $i64.neg_zero (result i64) (return (i64.const -0x0))) + (func $i64.not_octal (result i64) (return (i64.const 010))) (export "i32.test" $i32.test) (export "i32.umax" $i32.umax) @@ -25,6 +27,7 @@ (export "i32.alt_smin" $i32.alt_smin) (export "i32.inc_smin" $i32.inc_smin) (export "i32.neg_zero" $i32.neg_zero) + (export "i32.not_octal" $i32.not_octal) (export "i64.test" $i64.test) (export "i64.umax" $i64.umax) @@ -34,6 +37,7 @@ (export "i64.alt_smin" $i64.alt_smin) (export "i64.inc_smin" $i64.inc_smin) (export "i64.neg_zero" $i64.neg_zero) + (export "i64.not_octal" $i64.not_octal) ) (assert_return (invoke "i32.test") (i32.const 195940365)) @@ -44,6 +48,7 @@ (assert_return (invoke "i32.alt_smin") (i32.const -2147483648)) (assert_return (invoke "i32.inc_smin") (i32.const -2147483647)) (assert_return (invoke "i32.neg_zero") (i32.const 0)) +(assert_return (invoke "i32.not_octal") (i32.const 10)) (assert_return (invoke "i64.test") (i64.const 913028331277281902)) (assert_return (invoke "i64.umax") (i64.const -1)) @@ -53,3 +58,4 @@ (assert_return (invoke "i64.alt_smin") (i64.const -9223372036854775808)) (assert_return (invoke "i64.inc_smin") (i64.const -9223372036854775807)) (assert_return (invoke "i64.neg_zero") (i64.const 0)) +(assert_return (invoke "i64.not_octal") (i64.const 10)) diff --git a/ml-proto/test/left-to-right.wast b/ml-proto/test/left-to-right.wast index cb2ad78de9..2a7f8e6949 100644 --- a/ml-proto/test/left-to-right.wast +++ b/ml-proto/test/left-to-right.wast @@ -1,20 +1,59 @@ (module - (memory 9) - - ;; The idea is: We reset the memory, then the arithmetic instruction calls $*_left and $*_right. - ;; $*_left stores the number 1, and $*_right stores the number 2 (both at address 8) - ;; Then we read the value at address 8. If it's 0, the VM did an unwanted optimzation. - ;; If it's 1, then $*_right was called before $*_left. If it's 2, then everything's fine. - (func $reset (i32.store8 (i32.const 8) (i32.const 0))) - (func $get (result i32) (i32.load8_u (i32.const 8))) - (func $i32_left (result i32) (i32.store8 (i32.const 8) (i32.const 1)) (i32.const 0)) - (func $i32_right (result i32) (i32.store8 (i32.const 8) (i32.const 2)) (i32.const 1)) - (func $i64_left (result i64) (i32.store8 (i32.const 8) (i32.const 1)) (i64.const 0)) - (func $i64_right (result i64) (i32.store8 (i32.const 8) (i32.const 2)) (i64.const 1)) - (func $f32_left (result f32) (i32.store8 (i32.const 8) (i32.const 1)) (f32.const 0)) - (func $f32_right (result f32) (i32.store8 (i32.const 8) (i32.const 2)) (f32.const 1)) - (func $f64_left (result f64) (i32.store8 (i32.const 8) (i32.const 1)) (f64.const 0)) - (func $f64_right (result f64) (i32.store8 (i32.const 8) (i32.const 2)) (f64.const 1)) + (memory 12) + + (type $i32_T (func (param i32 i32) (result i32))) + (type $i64_T (func (param i64 i64) (result i32))) + (type $f32_T (func (param f32 f32) (result i32))) + (type $f64_T (func (param f64 f64) (result i32))) + (table $i32_t0 $i32_t1 $i64_t0 $i64_t1 $f32_t0 $f32_t1 $f64_t0 $f64_t1) + + (func $i32_t0 (type $i32_T) (i32.const -1)) + (func $i32_t1 (type $i32_T) (i32.const -2)) + (func $i64_t0 (type $i64_T) (i32.const -1)) + (func $i64_t1 (type $i64_T) (i32.const -2)) + (func $f32_t0 (type $f32_T) (i32.const -1)) + (func $f32_t1 (type $f32_T) (i32.const -2)) + (func $f64_t0 (type $f64_T) (i32.const -1)) + (func $f64_t1 (type $f64_T) (i32.const -2)) + + ;; The idea is: We reset the memory, then the instruction call $*_left, + ;; $*_right, $*_another, $*_callee (for indirect calls), and $*_bool (when a + ;; boolean value is needed). These functions all call bump, which shifts the + ;; memory starting at address 8 up a byte, and then store a unique value at + ;; address 8. Then we read the 4-byte value at address 8. It should contain + ;; the correct sequence of unique values if the calls were evaluated in the + ;; correct order. + + (func $reset (i32.store (i32.const 8) (i32.const 0))) + + (func $bump + (i32.store8 (i32.const 11) (i32.load8_u (i32.const 10))) + (i32.store8 (i32.const 10) (i32.load8_u (i32.const 9))) + (i32.store8 (i32.const 9) (i32.load8_u (i32.const 8))) + (i32.store8 (i32.const 8) (i32.const -3))) + + (func $get (result i32) (i32.load (i32.const 8))) + + (func $i32_left (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 1)) (i32.const 0)) + (func $i32_right (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 2)) (i32.const 1)) + (func $i32_another (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 3)) (i32.const 1)) + (func $i32_callee (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 4)) (i32.const 0)) + (func $i32_bool (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 5)) (i32.const 0)) + (func $i64_left (result i64) (call $bump) (i32.store8 (i32.const 8) (i32.const 1)) (i64.const 0)) + (func $i64_right (result i64) (call $bump) (i32.store8 (i32.const 8) (i32.const 2)) (i64.const 1)) + (func $i64_another (result i64) (call $bump) (i32.store8 (i32.const 8) (i32.const 3)) (i64.const 1)) + (func $i64_callee (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 4)) (i32.const 2)) + (func $i64_bool (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 5)) (i32.const 0)) + (func $f32_left (result f32) (call $bump) (i32.store8 (i32.const 8) (i32.const 1)) (f32.const 0)) + (func $f32_right (result f32) (call $bump) (i32.store8 (i32.const 8) (i32.const 2)) (f32.const 1)) + (func $f32_another (result f32) (call $bump) (i32.store8 (i32.const 8) (i32.const 3)) (f32.const 1)) + (func $f32_callee (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 4)) (i32.const 4)) + (func $f32_bool (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 5)) (i32.const 0)) + (func $f64_left (result f64) (call $bump) (i32.store8 (i32.const 8) (i32.const 1)) (f64.const 0)) + (func $f64_right (result f64) (call $bump) (i32.store8 (i32.const 8) (i32.const 2)) (f64.const 1)) + (func $f64_another (result f64) (call $bump) (i32.store8 (i32.const 8) (i32.const 3)) (f64.const 1)) + (func $f64_callee (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 4)) (i32.const 6)) + (func $f64_bool (result i32) (call $bump) (i32.store8 (i32.const 8) (i32.const 5)) (i32.const 0)) (func $i32_dummy (param i32 i32)) (func $i64_dummy (param i64 i64)) (func $f32_dummy (param f32 f32)) (func $f64_dummy (param f64 f64)) @@ -46,6 +85,8 @@ (func $i32_store8 (result i32) (call $reset) (i32.store8 (call $i32_left) (call $i32_right)) (call $get)) (func $i32_store16 (result i32) (call $reset) (i32.store16 (call $i32_left) (call $i32_right)) (call $get)) (func $i32_call (result i32) (call $reset) (call $i32_dummy (call $i32_left) (call $i32_right)) (call $get)) + (func $i32_call_indirect (result i32) (call $reset) (call_indirect $i32_T (call $i32_callee) (call $i32_right) (call $i32_another)) (call $get)) + (func $i32_select (result i32) (call $reset) (i32.select (call $i32_bool) (call $i32_left) (call $i32_right)) (call $get)) (func $i64_add (result i32) (call $reset) (i64.add (call $i64_left) (call $i64_right)) (call $get)) (func $i64_sub (result i32) (call $reset) (i64.sub (call $i64_left) (call $i64_right)) (call $get)) @@ -75,6 +116,8 @@ (func $i64_store16 (result i32) (call $reset) (i64.store16 (call $i32_left) (call $i64_right)) (call $get)) (func $i64_store32 (result i32) (call $reset) (i64.store32 (call $i32_left) (call $i64_right)) (call $get)) (func $i64_call (result i32) (call $reset) (call $i64_dummy (call $i64_left) (call $i64_right)) (call $get)) + (func $i64_call_indirect (result i32) (call $reset) (call_indirect $i64_T (call $i64_callee) (call $i64_right) (call $i64_another)) (call $get)) + (func $i64_select (result i32) (call $reset) (i64.select (call $i64_bool) (call $i64_left) (call $i64_right)) (call $get)) (func $f32_add (result i32) (call $reset) (f32.add (call $f32_left) (call $f32_right)) (call $get)) @@ -92,6 +135,8 @@ (func $f32_max (result i32) (call $reset) (f32.max (call $f32_left) (call $f32_right)) (call $get)) (func $f32_store (result i32) (call $reset) (f32.store (call $i32_left) (call $f32_right)) (call $get)) (func $f32_call (result i32) (call $reset) (call $f32_dummy (call $f32_left) (call $f32_right)) (call $get)) + (func $f32_call_indirect (result i32) (call $reset) (call_indirect $f32_T (call $f32_callee) (call $f32_right) (call $f32_another)) (call $get)) + (func $f32_select (result i32) (call $reset) (f32.select (call $f32_bool) (call $f32_left) (call $f32_right)) (call $get)) (func $f64_add (result i32) (call $reset) (f64.add (call $f64_left) (call $f64_right)) (call $get)) (func $f64_sub (result i32) (call $reset) (f64.sub (call $f64_left) (call $f64_right)) (call $get)) @@ -108,6 +153,8 @@ (func $f64_max (result i32) (call $reset) (f64.max (call $f64_left) (call $f64_right)) (call $get)) (func $f64_store (result i32) (call $reset) (f64.store (call $i32_left) (call $f64_right)) (call $get)) (func $f64_call (result i32) (call $reset) (call $f64_dummy (call $f64_left) (call $f64_right)) (call $get)) + (func $f64_call_indirect (result i32) (call $reset) (call_indirect $f64_T (call $f64_callee) (call $f64_right) (call $f64_another)) (call $get)) + (func $f64_select (result i32) (call $reset) (f64.select (call $f64_bool) (call $f64_left) (call $f64_right)) (call $get)) (export "i32_add" $i32_add) (export "i64_add" $i64_add) @@ -138,6 +185,8 @@ (export "i32_store16" $i32_store16) (export "i64_store16" $i64_store16) (export "i64_store32" $i64_store32) (export "i32_call" $i32_call) (export "i64_call" $i64_call) + (export "i32_call_indirect" $i32_call_indirect) (export "i64_call_indirect" $i64_call_indirect) + (export "i32_select" $i32_select) (export "i64_select" $i64_select) (export "f32_add" $f32_add) (export "f64_add" $f64_add) (export "f32_sub" $f32_sub) (export "f64_sub" $f64_sub) @@ -154,49 +203,57 @@ (export "f32_max" $f32_max) (export "f64_max" $f64_max) (export "f32_store" $f32_store) (export "f64_store" $f64_store) (export "f32_call" $f32_call) (export "f64_call" $f64_call) + (export "f32_call_indirect" $f32_call_indirect) (export "f64_call_indirect" $f64_call_indirect) + (export "f32_select" $f32_select) (export "f64_select" $f64_select) ) -(assert_return (invoke "i32_add") (i32.const 2)) (assert_return (invoke "i64_add") (i32.const 2)) -(assert_return (invoke "i32_sub") (i32.const 2)) (assert_return (invoke "i64_sub") (i32.const 2)) -(assert_return (invoke "i32_mul") (i32.const 2)) (assert_return (invoke "i64_mul") (i32.const 2)) -(assert_return (invoke "i32_div_s") (i32.const 2)) (assert_return (invoke "i64_div_s") (i32.const 2)) -(assert_return (invoke "i32_div_u") (i32.const 2)) (assert_return (invoke "i64_div_u") (i32.const 2)) -(assert_return (invoke "i32_rem_s") (i32.const 2)) (assert_return (invoke "i64_rem_s") (i32.const 2)) -(assert_return (invoke "i32_rem_u") (i32.const 2)) (assert_return (invoke "i64_rem_u") (i32.const 2)) -(assert_return (invoke "i32_and") (i32.const 2)) (assert_return (invoke "i64_and") (i32.const 2)) -(assert_return (invoke "i32_or") (i32.const 2)) (assert_return (invoke "i64_or") (i32.const 2)) -(assert_return (invoke "i32_xor") (i32.const 2)) (assert_return (invoke "i64_xor") (i32.const 2)) -(assert_return (invoke "i32_shl") (i32.const 2)) (assert_return (invoke "i64_shl") (i32.const 2)) -(assert_return (invoke "i32_shr_u") (i32.const 2)) (assert_return (invoke "i64_shr_u") (i32.const 2)) -(assert_return (invoke "i32_shr_s") (i32.const 2)) (assert_return (invoke "i64_shr_s") (i32.const 2)) -(assert_return (invoke "i32_eq") (i32.const 2)) (assert_return (invoke "i64_eq") (i32.const 2)) -(assert_return (invoke "i32_ne") (i32.const 2)) (assert_return (invoke "i64_ne") (i32.const 2)) -(assert_return (invoke "i32_lt_s") (i32.const 2)) (assert_return (invoke "i64_lt_s") (i32.const 2)) -(assert_return (invoke "i32_le_s") (i32.const 2)) (assert_return (invoke "i64_le_s") (i32.const 2)) -(assert_return (invoke "i32_lt_u") (i32.const 2)) (assert_return (invoke "i64_lt_u") (i32.const 2)) -(assert_return (invoke "i32_le_u") (i32.const 2)) (assert_return (invoke "i64_le_u") (i32.const 2)) -(assert_return (invoke "i32_gt_s") (i32.const 2)) (assert_return (invoke "i64_gt_s") (i32.const 2)) -(assert_return (invoke "i32_ge_s") (i32.const 2)) (assert_return (invoke "i64_ge_s") (i32.const 2)) -(assert_return (invoke "i32_gt_u") (i32.const 2)) (assert_return (invoke "i64_gt_u") (i32.const 2)) -(assert_return (invoke "i32_ge_u") (i32.const 2)) (assert_return (invoke "i64_ge_u") (i32.const 2)) -(assert_return (invoke "i32_store") (i32.const 2)) (assert_return (invoke "i64_store") (i32.const 2)) -(assert_return (invoke "i32_store8") (i32.const 2)) (assert_return (invoke "i64_store8") (i32.const 2)) -(assert_return (invoke "i32_store16") (i32.const 2)) (assert_return (invoke "i64_store16") (i32.const 2)) -(assert_return (invoke "i64_store32") (i32.const 2)) -(assert_return (invoke "i32_call") (i32.const 2)) (assert_return (invoke "i64_call") (i32.const 2)) - -(assert_return (invoke "f32_add") (i32.const 2)) (assert_return (invoke "f64_add") (i32.const 2)) -(assert_return (invoke "f32_sub") (i32.const 2)) (assert_return (invoke "f64_sub") (i32.const 2)) -(assert_return (invoke "f32_mul") (i32.const 2)) (assert_return (invoke "f64_mul") (i32.const 2)) -(assert_return (invoke "f32_div") (i32.const 2)) (assert_return (invoke "f64_div") (i32.const 2)) -(assert_return (invoke "f32_copysign") (i32.const 2))(assert_return (invoke "f64_copysign") (i32.const 2)) -(assert_return (invoke "f32_eq") (i32.const 2)) (assert_return (invoke "f64_eq") (i32.const 2)) -(assert_return (invoke "f32_ne") (i32.const 2)) (assert_return (invoke "f64_ne") (i32.const 2)) -(assert_return (invoke "f32_lt") (i32.const 2)) (assert_return (invoke "f64_lt") (i32.const 2)) -(assert_return (invoke "f32_le") (i32.const 2)) (assert_return (invoke "f64_le") (i32.const 2)) -(assert_return (invoke "f32_gt") (i32.const 2)) (assert_return (invoke "f64_gt") (i32.const 2)) -(assert_return (invoke "f32_ge") (i32.const 2)) (assert_return (invoke "f64_ge") (i32.const 2)) -(assert_return (invoke "f32_min") (i32.const 2)) (assert_return (invoke "f64_min") (i32.const 2)) -(assert_return (invoke "f32_max") (i32.const 2)) (assert_return (invoke "f64_max") (i32.const 2)) -(assert_return (invoke "f32_store") (i32.const 2)) (assert_return (invoke "f64_store") (i32.const 2)) -(assert_return (invoke "f32_call") (i32.const 2)) (assert_return (invoke "f64_call") (i32.const 2)) +(assert_return (invoke "i32_add") (i32.const 0x0102)) (assert_return (invoke "i64_add") (i32.const 0x0102)) +(assert_return (invoke "i32_sub") (i32.const 0x0102)) (assert_return (invoke "i64_sub") (i32.const 0x0102)) +(assert_return (invoke "i32_mul") (i32.const 0x0102)) (assert_return (invoke "i64_mul") (i32.const 0x0102)) +(assert_return (invoke "i32_div_s") (i32.const 0x0102)) (assert_return (invoke "i64_div_s") (i32.const 0x0102)) +(assert_return (invoke "i32_div_u") (i32.const 0x0102)) (assert_return (invoke "i64_div_u") (i32.const 0x0102)) +(assert_return (invoke "i32_rem_s") (i32.const 0x0102)) (assert_return (invoke "i64_rem_s") (i32.const 0x0102)) +(assert_return (invoke "i32_rem_u") (i32.const 0x0102)) (assert_return (invoke "i64_rem_u") (i32.const 0x0102)) +(assert_return (invoke "i32_and") (i32.const 0x0102)) (assert_return (invoke "i64_and") (i32.const 0x0102)) +(assert_return (invoke "i32_or") (i32.const 0x0102)) (assert_return (invoke "i64_or") (i32.const 0x0102)) +(assert_return (invoke "i32_xor") (i32.const 0x0102)) (assert_return (invoke "i64_xor") (i32.const 0x0102)) +(assert_return (invoke "i32_shl") (i32.const 0x0102)) (assert_return (invoke "i64_shl") (i32.const 0x0102)) +(assert_return (invoke "i32_shr_u") (i32.const 0x0102)) (assert_return (invoke "i64_shr_u") (i32.const 0x0102)) +(assert_return (invoke "i32_shr_s") (i32.const 0x0102)) (assert_return (invoke "i64_shr_s") (i32.const 0x0102)) +(assert_return (invoke "i32_eq") (i32.const 0x0102)) (assert_return (invoke "i64_eq") (i32.const 0x0102)) +(assert_return (invoke "i32_ne") (i32.const 0x0102)) (assert_return (invoke "i64_ne") (i32.const 0x0102)) +(assert_return (invoke "i32_lt_s") (i32.const 0x0102)) (assert_return (invoke "i64_lt_s") (i32.const 0x0102)) +(assert_return (invoke "i32_le_s") (i32.const 0x0102)) (assert_return (invoke "i64_le_s") (i32.const 0x0102)) +(assert_return (invoke "i32_lt_u") (i32.const 0x0102)) (assert_return (invoke "i64_lt_u") (i32.const 0x0102)) +(assert_return (invoke "i32_le_u") (i32.const 0x0102)) (assert_return (invoke "i64_le_u") (i32.const 0x0102)) +(assert_return (invoke "i32_gt_s") (i32.const 0x0102)) (assert_return (invoke "i64_gt_s") (i32.const 0x0102)) +(assert_return (invoke "i32_ge_s") (i32.const 0x0102)) (assert_return (invoke "i64_ge_s") (i32.const 0x0102)) +(assert_return (invoke "i32_gt_u") (i32.const 0x0102)) (assert_return (invoke "i64_gt_u") (i32.const 0x0102)) +(assert_return (invoke "i32_ge_u") (i32.const 0x0102)) (assert_return (invoke "i64_ge_u") (i32.const 0x0102)) +(assert_return (invoke "i32_store") (i32.const 0x0102)) (assert_return (invoke "i64_store") (i32.const 0x0102)) +(assert_return (invoke "i32_store8") (i32.const 0x0102)) (assert_return (invoke "i64_store8") (i32.const 0x0102)) +(assert_return (invoke "i32_store16") (i32.const 0x0102)) (assert_return (invoke "i64_store16") (i32.const 0x0102)) +(assert_return (invoke "i64_store32") (i32.const 0x0102)) +(assert_return (invoke "i32_call") (i32.const 0x0102)) (assert_return (invoke "i64_call") (i32.const 0x0102)) +(assert_return (invoke "i32_call_indirect") (i32.const 0x040203)) +(assert_return (invoke "i64_call_indirect") (i32.const 0x040203)) +(assert_return (invoke "i32_select") (i32.const 0x050102)) (assert_return (invoke "i64_select") (i32.const 0x050102)) + +(assert_return (invoke "f32_add") (i32.const 0x0102)) (assert_return (invoke "f64_add") (i32.const 0x0102)) +(assert_return (invoke "f32_sub") (i32.const 0x0102)) (assert_return (invoke "f64_sub") (i32.const 0x0102)) +(assert_return (invoke "f32_mul") (i32.const 0x0102)) (assert_return (invoke "f64_mul") (i32.const 0x0102)) +(assert_return (invoke "f32_div") (i32.const 0x0102)) (assert_return (invoke "f64_div") (i32.const 0x0102)) +(assert_return (invoke "f32_copysign") (i32.const 0x0102))(assert_return (invoke "f64_copysign") (i32.const 0x0102)) +(assert_return (invoke "f32_eq") (i32.const 0x0102)) (assert_return (invoke "f64_eq") (i32.const 0x0102)) +(assert_return (invoke "f32_ne") (i32.const 0x0102)) (assert_return (invoke "f64_ne") (i32.const 0x0102)) +(assert_return (invoke "f32_lt") (i32.const 0x0102)) (assert_return (invoke "f64_lt") (i32.const 0x0102)) +(assert_return (invoke "f32_le") (i32.const 0x0102)) (assert_return (invoke "f64_le") (i32.const 0x0102)) +(assert_return (invoke "f32_gt") (i32.const 0x0102)) (assert_return (invoke "f64_gt") (i32.const 0x0102)) +(assert_return (invoke "f32_ge") (i32.const 0x0102)) (assert_return (invoke "f64_ge") (i32.const 0x0102)) +(assert_return (invoke "f32_min") (i32.const 0x0102)) (assert_return (invoke "f64_min") (i32.const 0x0102)) +(assert_return (invoke "f32_max") (i32.const 0x0102)) (assert_return (invoke "f64_max") (i32.const 0x0102)) +(assert_return (invoke "f32_store") (i32.const 0x0102)) (assert_return (invoke "f64_store") (i32.const 0x0102)) +(assert_return (invoke "f32_call") (i32.const 0x0102)) (assert_return (invoke "f64_call") (i32.const 0x0102)) +(assert_return (invoke "f32_call_indirect") (i32.const 0x040203)) +(assert_return (invoke "f64_call_indirect") (i32.const 0x040203)) +(assert_return (invoke "f32_select") (i32.const 0x050102)) (assert_return (invoke "f64_select") (i32.const 0x050102)) diff --git a/ml-proto/test/memory.wast b/ml-proto/test/memory.wast index 444b85c2a2..f09b11fd0b 100644 --- a/ml-proto/test/memory.wast +++ b/ml-proto/test/memory.wast @@ -92,48 +92,44 @@ (func $aligned (result i32) (local i32 i32 i32) (set_local 0 (i32.const 10)) - (block - (loop - (if - (i32.eq (get_local 0) (i32.const 0)) - (br 1) - ) - (set_local 2 (i32.mul (get_local 0) (i32.const 4))) - (i32.store (get_local 2) (get_local 0)) - (set_local 1 (i32.load (get_local 2))) - (if - (i32.ne (get_local 0) (get_local 1)) - (return (i32.const 0)) - ) - (set_local 0 (i32.sub (get_local 0) (i32.const 1))) - (br 0) + (loop + (if + (i32.eq (get_local 0) (i32.const 0)) + (br 1) + ) + (set_local 2 (i32.mul (get_local 0) (i32.const 4))) + (i32.store (get_local 2) (get_local 0)) + (set_local 1 (i32.load (get_local 2))) + (if + (i32.ne (get_local 0) (get_local 1)) + (return (i32.const 0)) ) + (set_local 0 (i32.sub (get_local 0) (i32.const 1))) + (br 0) ) - (return (i32.const 1)) + (i32.const 1) ) ;; Unaligned read/write (func $unaligned (result i32) (local i32 f64 f64) (set_local 0 (i32.const 10)) - (block - (loop - (if - (i32.eq (get_local 0) (i32.const 0)) - (br 1) - ) - (set_local 2 (f64.convert_s/i32 (get_local 0))) - (f64.store align=1 (get_local 0) (get_local 2)) - (set_local 1 (f64.load align=1 (get_local 0))) - (if - (f64.ne (get_local 2) (get_local 1)) - (return (i32.const 0)) - ) - (set_local 0 (i32.sub (get_local 0) (i32.const 1))) - (br 0) + (loop + (if + (i32.eq (get_local 0) (i32.const 0)) + (br 1) + ) + (set_local 2 (f64.convert_s/i32 (get_local 0))) + (f64.store align=1 (get_local 0) (get_local 2)) + (set_local 1 (f64.load align=1 (get_local 0))) + (if + (f64.ne (get_local 2) (get_local 1)) + (return (i32.const 0)) ) + (set_local 0 (i32.sub (get_local 0) (i32.const 1))) + (br 0) ) - (return (i32.const 1)) + (i32.const 1) ) ;; Memory cast @@ -148,49 +144,49 @@ ) (i64.store align=1 (i32.const 9) (i64.const 0)) (i32.store16 align=1 (i32.const 15) (i32.const 16453)) - (return (f64.load align=1 (i32.const 9))) + (f64.load align=1 (i32.const 9)) ) ;; Sign and zero extending memory loads (func $i32_load8_s (param $i i32) (result i32) (i32.store8 (i32.const 8) (get_local $i)) - (return (i32.load8_s (i32.const 8))) + (i32.load8_s (i32.const 8)) ) (func $i32_load8_u (param $i i32) (result i32) (i32.store8 (i32.const 8) (get_local $i)) - (return (i32.load8_u (i32.const 8))) + (i32.load8_u (i32.const 8)) ) (func $i32_load16_s (param $i i32) (result i32) (i32.store16 (i32.const 8) (get_local $i)) - (return (i32.load16_s (i32.const 8))) + (i32.load16_s (i32.const 8)) ) (func $i32_load16_u (param $i i32) (result i32) (i32.store16 (i32.const 8) (get_local $i)) - (return (i32.load16_u (i32.const 8))) + (i32.load16_u (i32.const 8)) ) (func $i64_load8_s (param $i i64) (result i64) (i64.store8 (i32.const 8) (get_local $i)) - (return (i64.load8_s (i32.const 8))) + (i64.load8_s (i32.const 8)) ) (func $i64_load8_u (param $i i64) (result i64) (i64.store8 (i32.const 8) (get_local $i)) - (return (i64.load8_u (i32.const 8))) + (i64.load8_u (i32.const 8)) ) (func $i64_load16_s (param $i i64) (result i64) (i64.store16 (i32.const 8) (get_local $i)) - (return (i64.load16_s (i32.const 8))) + (i64.load16_s (i32.const 8)) ) (func $i64_load16_u (param $i i64) (result i64) (i64.store16 (i32.const 8) (get_local $i)) - (return (i64.load16_u (i32.const 8))) + (i64.load16_u (i32.const 8)) ) (func $i64_load32_s (param $i i64) (result i64) (i64.store32 (i32.const 8) (get_local $i)) - (return (i64.load32_s (i32.const 8))) + (i64.load32_s (i32.const 8)) ) (func $i64_load32_u (param $i i64) (result i64) (i64.store32 (i32.const 8) (get_local $i)) - (return (i64.load32_u (i32.const 8))) + (i64.load32_u (i32.const 8)) ) (export "data" $data) diff --git a/ml-proto/test/select.wast b/ml-proto/test/select.wast index bce69d2ba4..426e8389a3 100644 --- a/ml-proto/test/select.wast +++ b/ml-proto/test/select.wast @@ -36,10 +36,22 @@ (assert_return (invoke "select_i64" (i32.const 0xf0f0f0f0) (i64.const 2) (i64.const 1)) (i64.const 2)) (assert_return (invoke "select_f32" (i32.const 1) (f32.const nan) (f32.const 1)) (f32.const nan)) +(assert_return (invoke "select_f32" (i32.const 1) (f32.const nan:0x20304) (f32.const 1)) (f32.const nan:0x20304)) +(assert_return (invoke "select_f32" (i32.const 0) (f32.const nan) (f32.const 1)) (f32.const 1)) +(assert_return (invoke "select_f32" (i32.const 0) (f32.const nan:0x20304) (f32.const 1)) (f32.const 1)) +(assert_return (invoke "select_f32" (i32.const 1) (f32.const 2) (f32.const nan)) (f32.const 2)) +(assert_return (invoke "select_f32" (i32.const 1) (f32.const 2) (f32.const nan:0x20304)) (f32.const 2)) (assert_return (invoke "select_f32" (i32.const 0) (f32.const 2) (f32.const nan)) (f32.const nan)) +(assert_return (invoke "select_f32" (i32.const 0) (f32.const 2) (f32.const nan:0x20304)) (f32.const nan:0x20304)) (assert_return (invoke "select_f64" (i32.const 1) (f64.const nan) (f64.const 1)) (f64.const nan)) +(assert_return (invoke "select_f64" (i32.const 1) (f64.const nan:0x20304) (f64.const 1)) (f64.const nan:0x20304)) +(assert_return (invoke "select_f64" (i32.const 0) (f64.const nan) (f64.const 1)) (f64.const 1)) +(assert_return (invoke "select_f64" (i32.const 0) (f64.const nan:0x20304) (f64.const 1)) (f64.const 1)) +(assert_return (invoke "select_f64" (i32.const 1) (f64.const 2) (f64.const nan)) (f64.const 2)) +(assert_return (invoke "select_f64" (i32.const 1) (f64.const 2) (f64.const nan:0x20304)) (f64.const 2)) (assert_return (invoke "select_f64" (i32.const 0) (f64.const 2) (f64.const nan)) (f64.const nan)) +(assert_return (invoke "select_f64" (i32.const 0) (f64.const 2) (f64.const nan:0x20304)) (f64.const nan:0x20304)) (assert_trap (invoke "select_trap_l" (i32.const 1)) "unreachable executed") (assert_trap (invoke "select_trap_l" (i32.const 0)) "unreachable executed")