diff --git a/ml-proto/runtests.py b/ml-proto/runtests.py index 609297cc19..affca0b5bd 100755 --- a/ml-proto/runtests.py +++ b/ml-proto/runtests.py @@ -9,6 +9,9 @@ class RunTests(unittest.TestCase): def _runTestFile(self, shortName, fileName, interpreterPath): + # HACK: Windows python compatibility + fileName = fileName.replace("\\", "/") + logPath = fileName.replace("test/", "test/output/").replace(".wasm", ".wasm.log") try: os.remove(logPath) @@ -59,6 +62,8 @@ def rebuild_interpreter(path): if __name__ == "__main__": interpreterPath = os.path.abspath("src/main.native") + # HACK: Windows python compatibility + interpreterPath = interpreterPath.replace("\\", "/") try: os.makedirs("test/output/") diff --git a/ml-proto/test/countUp.wasm b/ml-proto/test/countUp.wasm new file mode 100644 index 0000000000..9150b30ffd --- /dev/null +++ b/ml-proto/test/countUp.wasm @@ -0,0 +1,75 @@ +;; CountUp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + +(module + + (func $Program_countUp + (param $outOffset i32) (param $count i32) (local $i i32) + + (block + + ;; for (var (@ = 0); ...) + (setlocal $i (const.i32 0)) + + (label $loop_0 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $i) + (getlocal $count) + ) + (nop) + (break $loop_0) + ) + + ;; for (...) { + (stores.1.i32 + (mul.i32 + (add.i32 + (getlocal $outOffset) + (getlocal $i) + ) + (const.i32 4) + ) + (getlocal $i) + ) + + ;; for (...; ...; ) + (setlocal $i (add.i32 + (getlocal $i) + (const.i32 1) + )) + ) + ) + ) + ) + + (func $Program_readI32 + (param $base i32) (param $offset i32) + (result i32) + + (return (loads.1.i32 (mul.i32 + (add.i32 + (getlocal $base) + (getlocal $offset) + ) + (const.i32 4) + ) )) + ) + + (export "countUp" $Program_countUp) + (export "readI32" $Program_readI32) + + (memory 4096 4096) + +) + + +(invoke "countUp" (const.i32 0) (const.i32 32) ) +(invoke "countUp" (const.i32 16) (const.i32 4) ) +(asserteq (invoke "readI32" (const.i32 0) (const.i32 0) ) (const.i32 0) ) +(asserteq (invoke "readI32" (const.i32 0) (const.i32 2) ) (const.i32 2) ) +(asserteq (invoke "readI32" (const.i32 0) (const.i32 31) ) (const.i32 31) ) +(asserteq (invoke "readI32" (const.i32 16) (const.i32 0) ) (const.i32 0) ) +(asserteq (invoke "readI32" (const.i32 16) (const.i32 3) ) (const.i32 3) ) diff --git a/ml-proto/test/fannkuch.broken-wasm b/ml-proto/test/fannkuch.broken-wasm new file mode 100644 index 0000000000..8c1c846dc3 --- /dev/null +++ b/ml-proto/test/fannkuch.broken-wasm @@ -0,0 +1,507 @@ +;; FannkuchRedux, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + +(module + + (func $Program_fannkuch + (param $n i32) (local $sign i32) (local $maxflips i32) (local $sum i32) + (local $j i32) (local $q0 i32) (local $k i32) (local $flips i32) + (local $qq i32) (local $l i32) (local $m i32) (local $t i32) + (local $t3 i32) (local $i2 i32) (local $sx i32) (local $j2 i32) + + (local $currentLabel_0 i32) + + (block + + ;; LabelGroup 0 (starting at $entry0) + (setlocal $currentLabel_0 (const.i32 0)) + + (label $labelgroup_0 (loop (label $labelgroup_0_dispatch + ;; Begin Label $entry0 + (if (eq.i32 (getlocal $currentLabel_0) (const.i32 0)) + (block + (setlocal $sign (const.i32 1)) + (setlocal $maxflips (const.i32 0)) + (setlocal $sum (const.i32 0)) + + ;; for (var (@ = 0); ...) + (setlocal $j (const.i32 0)) + + (label $loop_0 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $j) + (getlocal $n) + ) + (nop) + (break $loop_0) + ) + + ;; for (...) { + (block + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 32) + (getlocal $j) + ) + (const.i32 4) + ) + (getlocal $j) + ) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $j) + ) + (const.i32 4) + ) + (getlocal $j) + ) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 96) + (getlocal $j) + ) + (const.i32 4) + ) + (getlocal $j) + ) + ) + + ;; for (...; ...; ) + (setlocal $j (add.i32 + (getlocal $j) + (const.i32 1) + )) + ) + ) + + ;; while () + (label $loop_1 + (loop + + (if + (const.i32 1) + (nop) + (break $loop_1) + ) + + ;; while (...) { + (block + (setlocal $q0 (loads.1.i32 (const.i32 128) )) + + (if + (neq.i32 + (getlocal $q0) + (const.i32 0) + ) + (block + + ;; for (var (@ = 1); ...) + (setlocal $k (const.i32 1)) + + (label $loop_2 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $k) + (getlocal $n) + ) + (nop) + (break $loop_2) + ) + + ;; for (...) { + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $k) + ) + (const.i32 4) + ) + (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 32) + (getlocal $k) + ) + (const.i32 4) + ) ) + ) + + ;; for (...; ...; ) + (setlocal $k (add.i32 + (getlocal $k) + (const.i32 1) + )) + ) + ) + (setlocal $flips (const.i32 1)) + + ;; while () + (label $loop_3 + (loop + + (if + (const.i32 1) + (nop) + (break $loop_3) + ) + + ;; while (...) { + (block + (setlocal $qq (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $q0) + ) + (const.i32 4) + ) )) + + (if + (eq.i32 + (getlocal $qq) + (const.i32 0) + ) + (break $loop_3) + ) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $q0) + ) + (const.i32 4) + ) + (getlocal $q0) + ) + + (if + (ges.i32 + (getlocal $q0) + (const.i32 3) + ) + (block + (setlocal $l (const.i32 1)) + (setlocal $m (sub.i32 + (getlocal $q0) + (const.i32 1) + )) + + ;; do { + (label $loop_4 + (loop + (block + (setlocal $t (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $l) + ) + (const.i32 4) + ) )) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $l) + ) + (const.i32 4) + ) + (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $m) + ) + (const.i32 4) + ) ) + ) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 64) + (getlocal $m) + ) + (const.i32 4) + ) + (getlocal $t) + ) + (setlocal $l (add.i32 + (getlocal $l) + (const.i32 1) + )) + (setlocal $m (sub.i32 + (getlocal $m) + (const.i32 1) + )) + ) + + ;; do { ... } while ((@ < @)) + + (if + (lts.i32 + (getlocal $l) + (getlocal $m) + ) + (nop) + (break $loop_4) + ) + ) + ) + ) + ) + (setlocal $q0 (getlocal $qq)) + (setlocal $flips (add.i32 + (getlocal $flips) + (const.i32 1) + )) + ) + ) + ) + (setlocal $sum (add.i32 + (getlocal $sum) + (mul.i32 + (getlocal $sign) + (getlocal $flips) + ) + )) + + (if + (gts.i32 + (getlocal $flips) + (getlocal $maxflips) + ) + (setlocal $maxflips (getlocal $flips)) + ) + ) + ) + + (if + (eq.i32 + (getlocal $sign) + (const.i32 1) + ) + (block + (stores.1.i32 + (const.i32 132) + (loads.1.i32 (const.i32 128) ) + ) + (stores.1.i32 + (const.i32 128) + (loads.1.i32 (const.i32 132) ) + ) + (setlocal $sign (const.i32 -1)) + ) + (block + (setlocal $t3 (loads.1.i32 (const.i32 132) )) + (stores.1.i32 + (const.i32 132) + (loads.1.i32 (const.i32 136) ) + ) + (stores.1.i32 + (const.i32 136) + (getlocal $t3) + ) + (setlocal $sign (const.i32 1)) + + ;; for (var (@ = 2); ...) + (setlocal $i2 (const.i32 2)) + + (label $loop_5 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $i2) + (getlocal $n) + ) + (nop) + (break $loop_5) + ) + + ;; for (...) { + (block + (setlocal $sx (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 96) + (getlocal $i2) + ) + (const.i32 4) + ) )) + + (if + (neq.i32 + (getlocal $sx) + (const.i32 0) + ) + (block + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 96) + (getlocal $i2) + ) + (const.i32 4) + ) + (sub.i32 + (getlocal $sx) + (const.i32 1) + ) + ) + (break $loop_5) + ) + ) + + (if + (eq.i32 + (getlocal $i2) + (sub.i32 + (getlocal $n) + (const.i32 1) + ) + ) + ;; goto Block_8 + (block (setlocal $currentLabel_0 (const.i32 1)) (break $labelgroup_0_dispatch) ) + ) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 96) + (getlocal $i2) + ) + (const.i32 4) + ) + (getlocal $i2) + ) + (setlocal $t3 (loads.1.i32 (const.i32 128) )) + + ;; for (var (@ = 0); ...) + (setlocal $j2 (const.i32 0)) + + (label $loop_6 + (loop + ;; for (...; (@ <= @); ...) + + (if + (les.i32 + (getlocal $j2) + (getlocal $i2) + ) + (nop) + (break $loop_6) + ) + + ;; for (...) { + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 32) + (getlocal $j2) + ) + (const.i32 4) + ) + (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 32) + (add.i32 + (getlocal $j2) + (const.i32 1) + ) + ) + (const.i32 4) + ) ) + ) + + ;; for (...; ...; ) + (setlocal $j2 (add.i32 + (getlocal $j2) + (const.i32 1) + )) + ) + ) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 32) + (add.i32 + (getlocal $i2) + (const.i32 1) + ) + ) + (const.i32 4) + ) + (getlocal $t3) + ) + ) + + ;; for (...; ...; ) + (setlocal $i2 (add.i32 + (getlocal $i2) + (const.i32 1) + )) + ) + ) + ) + ) + ) + ) + ) + ) + + ) + ;; End Label $entry0 + + ;; Begin Label Block_8 + (if (eq.i32 (getlocal $currentLabel_0) (const.i32 1)) + (block + (stores.1.i32 + (const.i32 0) + (getlocal $sum) + ) + (stores.1.i32 + (const.i32 4) + (getlocal $maxflips) + ) + ) + + ) + ;; End Label Block_8 + + ;; Fallthrough exit from labelgroup 0 + (break $labelgroup_0) + ) + )) + ) + ) + + (func $Program_readI32 + (param $base i32) (param $offset i32) + (result i32) + + (return (loads.1.i32 (mul.i32 + (add.i32 + (getlocal $base) + (getlocal $offset) + ) + (const.i32 4) + ) )) + ) + + (export "fannkuch" $Program_fannkuch) + (export "readI32" $Program_readI32) + + (memory 4096 4096) + +) + + +(invoke "fannkuch" (const.i32 7) ) +(asserteq (invoke "readI32" (const.i32 0) (const.i32 0) ) (const.i32 228) ) +(asserteq (invoke "readI32" (const.i32 0) (const.i32 1) ) (const.i32 16) ) diff --git a/ml-proto/test/goto.wasm b/ml-proto/test/goto.wasm new file mode 100644 index 0000000000..82fdd34439 --- /dev/null +++ b/ml-proto/test/goto.wasm @@ -0,0 +1,209 @@ +;; Goto, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + +(module + + (func $Program_AddResult + (param $result i32) (local $count i32) + + (block + (setlocal $count (call $Program_get_ResultCount)) + (storeu.1.i8 + (add.i32 + (const.i32 0) + (getlocal $count) + ) + (getlocal $result) + ) + (call $Program_set_ResultCount (add.i32 + (getlocal $count) + (const.i32 1) + )) + ) + ) + + (func $Program_Clear + (param $offset i32) (param $count i32) (local $i i32) + + (block + + ;; for (var (@ = 0); ...) + (setlocal $i (const.i32 0)) + + (label $loop_0 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $i) + (getlocal $count) + ) + (nop) + (break $loop_0) + ) + + ;; for (...) { + (storeu.1.i8 + (add.i32 + (getlocal $offset) + (getlocal $i) + ) + (const.i32 0) + ) + + ;; for (...; ...; ) + (setlocal $i (add.i32 + (getlocal $i) + (const.i32 1) + )) + ) + ) + ) + ) + + (func $Program_get_ResultCount + + (result i32) + + (return (load_global $Program_ResultCount_value)) + ) + + (func $Program_GetResult + (param $index i32) + (result i32) + + (return (loadu.1.i8 (add.i32 + (const.i32 0) + (getlocal $index) + ) )) + ) + + (func $Program_Gotos + + (block + (call $Program_set_ResultCount (const.i32 0)) + (call $Program_Clear (const.i32 0) (const.i32 128) ) + (call $Program_GotosInner ) + ) + ) + + (func $Program_GotosInner + (local $i i32) + (local $currentLabel_0 i32) + + (block + (setlocal $i (const.i32 0)) + + ;; while () + (label $loop_0 + (loop + + (if + (const.i32 1) + (nop) + (break $loop_0) + ) + + ;; while (...) { + (block + + ;; LabelGroup 0 (starting at IL_03) + (setlocal $currentLabel_0 (const.i32 0)) + + (label $labelgroup_0 (loop (label $labelgroup_0_dispatch + ;; Begin Label IL_03 + (if (eq.i32 (getlocal $currentLabel_0) (const.i32 0)) + (block + (setlocal $i (add.i32 + (getlocal $i) + (const.i32 1) + )) + (call $Program_AddResult (const.i32 1) ) + + (label $loop_1 + (loop + ;; for (...; (@ < 16); ...) + + (if + (lts.i32 + (getlocal $i) + (const.i32 16) + ) + (nop) + (break $loop_1) + ) + + ;; for (...) { + (block + + (if + (eq.i32 + (getlocal $i) + (const.i32 8) + ) + ;; goto IL_03 + (block (setlocal $currentLabel_0 (const.i32 0)) (break $labelgroup_0_dispatch) ) + ) + (call $Program_AddResult (const.i32 3) ) + ) + + ;; for (...; ...; ) + (setlocal $i (add.i32 + (getlocal $i) + (const.i32 1) + )) + ) + ) + (break $loop_0) + ) + + ) + ;; End Label IL_03 + + ;; Fallthrough exit from labelgroup 0 + (break $labelgroup_0) + ) + )) + ) + ) + ) + ) + ) + + (func $Program_set_ResultCount + (param $value i32) + + (store_global $Program_ResultCount_value (getlocal $value)) + ) + + (export "get_ResultCount" $Program_get_ResultCount) + (export "getResult" $Program_GetResult) + (export "gotos" $Program_Gotos) + (export "set_ResultCount" $Program_set_ResultCount) + + (global $Program_ResultCount_value i32) + + (memory 1024 1024) + +) + + +(invoke "gotos" ) +(asserteq (invoke "get_ResultCount" ) (const.i32 16) ) +(asserteq (invoke "getResult" (const.i32 0) ) (const.i32 1) ) +(asserteq (invoke "getResult" (const.i32 1) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 2) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 3) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 4) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 5) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 6) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 7) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 8) ) (const.i32 1) ) +(asserteq (invoke "getResult" (const.i32 9) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 10) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 11) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 12) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 13) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 14) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 15) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 16) ) (const.i32 0) ) diff --git a/ml-proto/test/sieve.wasm b/ml-proto/test/sieve.wasm new file mode 100644 index 0000000000..64c3f0076b --- /dev/null +++ b/ml-proto/test/sieve.wasm @@ -0,0 +1,216 @@ +;; Sieve, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + +(module + + (func $Program_AddResult + (param $result i32) (local $count i32) + + (block + (setlocal $count (call $Program_get_ResultCount)) + (stores.1.i32 + (mul.i32 + (add.i32 + (const.i32 0) + (getlocal $count) + ) + (const.i32 4) + ) + (getlocal $result) + ) + (call $Program_set_ResultCount (add.i32 + (getlocal $count) + (const.i32 1) + )) + ) + ) + + (func $Program_Clear + (param $offset i32) (param $count i32) (local $i i32) + + (block + + ;; for (var (@ = 0); ...) + (setlocal $i (const.i32 0)) + + (label $loop_0 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $i) + (getlocal $count) + ) + (nop) + (break $loop_0) + ) + + ;; for (...) { + (storeu.1.i8 + (add.i32 + (getlocal $offset) + (getlocal $i) + ) + (const.i32 0) + ) + + ;; for (...; ...; ) + (setlocal $i (add.i32 + (getlocal $i) + (const.i32 1) + )) + ) + ) + ) + ) + + (func $Program_get_ResultCount + + (result i32) + + (return (load_global $Program_ResultCount_value)) + ) + + (func $Program_GetResult + (param $index i32) + (result i32) + + (return (loads.1.i32 (mul.i32 + (add.i32 + (const.i32 0) + (getlocal $index) + ) + (const.i32 4) + ) )) + ) + + (func $Program_set_ResultCount + (param $value i32) + + (store_global $Program_ResultCount_value (getlocal $value)) + ) + + (func $Program_Sieve + (param $target i32) (local $squareRoot f64) (local $candidate i32) (local $multiple i32) + + (block + (call $Program_set_ResultCount (const.i32 0)) + (call $Program_Clear (const.i32 0) (const.i32 16384) ) + (call $Program_Clear (const.i32 16388) (getlocal $target) ) + (setlocal $squareRoot (sqrt.f64 (converts.i32.f64 (getlocal $target)) )) + (call $Program_AddResult (const.i32 2) ) + + ;; for (var (@ = 3); ...) + (setlocal $candidate (const.i32 3)) + + (label $loop_0 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $candidate) + (getlocal $target) + ) + (nop) + (break $loop_0) + ) + + ;; for (...) { + (block + + (if + (eq.i32 + (loadu.1.i8 (add.i32 + (const.i32 16388) + (getlocal $candidate) + ) ) + (const.i32 0) + ) + (block + + (if + (lt.f64 + (converts.i32.f64 (getlocal $candidate)) + (getlocal $squareRoot) + ) + (block + + ;; for (var (@ = (@ * @)); ...) + (setlocal $multiple (mul.i32 + (getlocal $candidate) + (getlocal $candidate) + )) + + (label $loop_1 + (loop + ;; for (...; (@ < @); ...) + + (if + (lts.i32 + (getlocal $multiple) + (getlocal $target) + ) + (nop) + (break $loop_1) + ) + + ;; for (...) { + (storeu.1.i8 + (add.i32 + (const.i32 16388) + (getlocal $multiple) + ) + (const.i32 1) + ) + + ;; for (...; ...; ) + (setlocal $multiple (add.i32 + (getlocal $multiple) + (mul.i32 + (const.i32 2) + (getlocal $candidate) + ) + )) + ) + ) + ) + ) + (call $Program_AddResult (getlocal $candidate) ) + ) + ) + ) + + ;; for (...; ...; ) + (setlocal $candidate (add.i32 + (getlocal $candidate) + (const.i32 2) + )) + ) + ) + ) + ) + + (export "get_ResultCount" $Program_get_ResultCount) + (export "getResult" $Program_GetResult) + (export "set_ResultCount" $Program_set_ResultCount) + (export "sieve" $Program_Sieve) + + (global $Program_ResultCount_value i32) + + (memory 131072 131072) + +) + + +(invoke "sieve" (const.i32 24) ) +(asserteq (invoke "get_ResultCount" ) (const.i32 9) ) +(asserteq (invoke "getResult" (const.i32 0) ) (const.i32 2) ) +(asserteq (invoke "getResult" (const.i32 1) ) (const.i32 3) ) +(asserteq (invoke "getResult" (const.i32 2) ) (const.i32 5) ) +(asserteq (invoke "getResult" (const.i32 3) ) (const.i32 7) ) +(asserteq (invoke "getResult" (const.i32 4) ) (const.i32 11) ) +(asserteq (invoke "getResult" (const.i32 5) ) (const.i32 13) ) +(asserteq (invoke "getResult" (const.i32 6) ) (const.i32 17) ) +(asserteq (invoke "getResult" (const.i32 7) ) (const.i32 19) ) +(asserteq (invoke "getResult" (const.i32 8) ) (const.i32 23) )