diff --git a/examples/call_indirect.wast b/examples/call_indirect.wast new file mode 100644 index 00000000000..613b5bfb4fe --- /dev/null +++ b/examples/call_indirect.wast @@ -0,0 +1,30 @@ +(module + (type $multiply_signature (func (param i32 i32) (result i32))) + (table 1 1 anyfunc) + (elem (i32.const 0) $multiply) + (memory $0 1) + (export "memory" (memory $0)) + (export "dispatch" (func $dispatch)) + (export "multiply" (func $multiply)) + (export "main" (func $main)) + (func $dispatch (; 0 ;) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (call_indirect (type $multiply_signature) + (get_local $1) + (get_local $2) + (get_local $0) + ) + ) + (func $multiply (; 1 ;) (type $multiply_signature) (param $0 i32) (param $1 i32) (result i32) + (i32.mul + (get_local $1) + (get_local $0) + ) + ) + (func $main (; 2 ;) (result i32) + (call $dispatch + (i32.const 0) + (i32.const 20) + (i32.const 30) + ) + ) +) diff --git a/spectests/call_indirect.wast b/spectests/call_indirect.wast new file mode 100644 index 00000000000..32a608263c7 --- /dev/null +++ b/spectests/call_indirect.wast @@ -0,0 +1,779 @@ +;; Test `call_indirect` operator + +(module + ;; Auxiliary definitions + (type $proc (func)) + (type $out-i32 (func (result i32))) + (type $out-i64 (func (result i64))) + (type $out-f32 (func (result f32))) + (type $out-f64 (func (result f64))) + (type $over-i32 (func (param i32) (result i32))) + (type $over-i64 (func (param i64) (result i64))) + (type $over-f32 (func (param f32) (result f32))) + (type $over-f64 (func (param f64) (result f64))) + (type $f32-i32 (func (param f32 i32) (result i32))) + (type $i32-i64 (func (param i32 i64) (result i64))) + (type $f64-f32 (func (param f64 f32) (result f32))) + (type $i64-f64 (func (param i64 f64) (result f64))) + (type $over-i32-duplicate (func (param i32) (result i32))) + (type $over-i64-duplicate (func (param i64) (result i64))) + (type $over-f32-duplicate (func (param f32) (result f32))) + (type $over-f64-duplicate (func (param f64) (result f64))) + + (func $const-i32 (type $out-i32) (i32.const 0x132)) + (func $const-i64 (type $out-i64) (i64.const 0x164)) + (func $const-f32 (type $out-f32) (f32.const 0xf32)) + (func $const-f64 (type $out-f64) (f64.const 0xf64)) + + (func $id-i32 (type $over-i32) (get_local 0)) + (func $id-i64 (type $over-i64) (get_local 0)) + (func $id-f32 (type $over-f32) (get_local 0)) + (func $id-f64 (type $over-f64) (get_local 0)) + + (func $i32-i64 (type $i32-i64) (get_local 1)) + (func $i64-f64 (type $i64-f64) (get_local 1)) + (func $f32-i32 (type $f32-i32) (get_local 1)) + (func $f64-f32 (type $f64-f32) (get_local 1)) + + (func $over-i32-duplicate (type $over-i32-duplicate) (get_local 0)) + (func $over-i64-duplicate (type $over-i64-duplicate) (get_local 0)) + (func $over-f32-duplicate (type $over-f32-duplicate) (get_local 0)) + (func $over-f64-duplicate (type $over-f64-duplicate) (get_local 0)) + + (table anyfunc + (elem + $const-i32 $const-i64 $const-f32 $const-f64 + $id-i32 $id-i64 $id-f32 $id-f64 + $f32-i32 $i32-i64 $f64-f32 $i64-f64 + $fac-i64 $fib-i64 $even $odd + $runaway $mutual-runaway1 $mutual-runaway2 + $over-i32-duplicate $over-i64-duplicate + $over-f32-duplicate $over-f64-duplicate + $fac-i32 $fac-f32 $fac-f64 + $fib-i32 $fib-f32 $fib-f64 + ) + ) + + ;; Syntax + + (func + (call_indirect (i32.const 0)) + (call_indirect (param i64) (i64.const 0) (i32.const 0)) + (call_indirect (param i64) (param) (param f64 i32 i64) + (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) + ) + (call_indirect (result) (i32.const 0)) + (drop (i32.eqz (call_indirect (result i32) (i32.const 0)))) + (drop (i32.eqz (call_indirect (result i32) (result) (i32.const 0)))) + (drop (i32.eqz + (call_indirect (param i64) (result i32) (i64.const 0) (i32.const 0)) + )) + (drop (i32.eqz + (call_indirect + (param) (param i64) (param) (param f64 i32 i64) (param) (param) + (result) (result i32) (result) (result) + (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) + ) + )) + (drop (i64.eqz + (call_indirect (type $over-i64) (param i64) (result i64) + (i64.const 0) (i32.const 0) + ) + )) + ) + + ;; Typing + + (func (export "type-i32") (result i32) + (call_indirect (type $out-i32) (i32.const 0)) + ) + (func (export "type-i64") (result i64) + (call_indirect (type $out-i64) (i32.const 1)) + ) + (func (export "type-f32") (result f32) + (call_indirect (type $out-f32) (i32.const 2)) + ) + (func (export "type-f64") (result f64) + (call_indirect (type $out-f64) (i32.const 3)) + ) + + (func (export "type-index") (result i64) + (call_indirect (type $over-i64) (i64.const 100) (i32.const 5)) + ) + + (func (export "type-first-i32") (result i32) + (call_indirect (type $over-i32) (i32.const 32) (i32.const 4)) + ) + (func (export "type-first-i64") (result i64) + (call_indirect (type $over-i64) (i64.const 64) (i32.const 5)) + ) + (func (export "type-first-f32") (result f32) + (call_indirect (type $over-f32) (f32.const 1.32) (i32.const 6)) + ) + (func (export "type-first-f64") (result f64) + (call_indirect (type $over-f64) (f64.const 1.64) (i32.const 7)) + ) + + (func (export "type-second-i32") (result i32) + (call_indirect (type $f32-i32) (f32.const 32.1) (i32.const 32) (i32.const 8)) + ) + (func (export "type-second-i64") (result i64) + (call_indirect (type $i32-i64) (i32.const 32) (i64.const 64) (i32.const 9)) + ) + (func (export "type-second-f32") (result f32) + (call_indirect (type $f64-f32) (f64.const 64) (f32.const 32) (i32.const 10)) + ) + (func (export "type-second-f64") (result f64) + (call_indirect (type $i64-f64) (i64.const 64) (f64.const 64.1) (i32.const 11)) + ) + + ;; Dispatch + + (func (export "dispatch") (param i32 i64) (result i64) + (call_indirect (type $over-i64) (get_local 1) (get_local 0)) + ) + + (func (export "dispatch-structural-i64") (param i32) (result i64) + (call_indirect (type $over-i64-duplicate) (i64.const 9) (get_local 0)) + ) + (func (export "dispatch-structural-i32") (param i32) (result i32) + (call_indirect (type $over-i32-duplicate) (i32.const 9) (get_local 0)) + ) + (func (export "dispatch-structural-f32") (param i32) (result f32) + (call_indirect (type $over-f32-duplicate) (f32.const 9.0) (get_local 0)) + ) + (func (export "dispatch-structural-f64") (param i32) (result f64) + (call_indirect (type $over-f64-duplicate) (f64.const 9.0) (get_local 0)) + ) + + ;; Recursion + + (func $fac-i64 (export "fac-i64") (type $over-i64) + (if (result i64) (i64.eqz (get_local 0)) + (then (i64.const 1)) + (else + (i64.mul + (get_local 0) + (call_indirect (type $over-i64) + (i64.sub (get_local 0) (i64.const 1)) + (i32.const 12) + ) + ) + ) + ) + ) + + (func $fib-i64 (export "fib-i64") (type $over-i64) + (if (result i64) (i64.le_u (get_local 0) (i64.const 1)) + (then (i64.const 1)) + (else + (i64.add + (call_indirect (type $over-i64) + (i64.sub (get_local 0) (i64.const 2)) + (i32.const 13) + ) + (call_indirect (type $over-i64) + (i64.sub (get_local 0) (i64.const 1)) + (i32.const 13) + ) + ) + ) + ) + ) + + (func $fac-i32 (export "fac-i32") (type $over-i32) + (if (result i32) (i32.eqz (get_local 0)) + (then (i32.const 1)) + (else + (i32.mul + (get_local 0) + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 23) + ) + ) + ) + ) + ) + + (func $fac-f32 (export "fac-f32") (type $over-f32) + (if (result f32) (f32.eq (get_local 0) (f32.const 0.0)) + (then (f32.const 1.0)) + (else + (f32.mul + (get_local 0) + (call_indirect (type $over-f32) + (f32.sub (get_local 0) (f32.const 1.0)) + (i32.const 24) + ) + ) + ) + ) + ) + + (func $fac-f64 (export "fac-f64") (type $over-f64) + (if (result f64) (f64.eq (get_local 0) (f64.const 0.0)) + (then (f64.const 1.0)) + (else + (f64.mul + (get_local 0) + (call_indirect (type $over-f64) + (f64.sub (get_local 0) (f64.const 1.0)) + (i32.const 25) + ) + ) + ) + ) + ) + + (func $fib-i32 (export "fib-i32") (type $over-i32) + (if (result i32) (i32.le_u (get_local 0) (i32.const 1)) + (then (i32.const 1)) + (else + (i32.add + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 2)) + (i32.const 26) + ) + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 26) + ) + ) + ) + ) + ) + + (func $fib-f32 (export "fib-f32") (type $over-f32) + (if (result f32) (f32.le (get_local 0) (f32.const 1.0)) + (then (f32.const 1.0)) + (else + (f32.add + (call_indirect (type $over-f32) + (f32.sub (get_local 0) (f32.const 2.0)) + (i32.const 27) + ) + (call_indirect (type $over-f32) + (f32.sub (get_local 0) (f32.const 1.0)) + (i32.const 27) + ) + ) + ) + ) + ) + + (func $fib-f64 (export "fib-f64") (type $over-f64) + (if (result f64) (f64.le (get_local 0) (f64.const 1.0)) + (then (f64.const 1.0)) + (else + (f64.add + (call_indirect (type $over-f64) + (f64.sub (get_local 0) (f64.const 2.0)) + (i32.const 28) + ) + (call_indirect (type $over-f64) + (f64.sub (get_local 0) (f64.const 1.0)) + (i32.const 28) + ) + ) + ) + ) + ) + + (func $even (export "even") (param i32) (result i32) + (if (result i32) (i32.eqz (get_local 0)) + (then (i32.const 44)) + (else + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 15) + ) + ) + ) + ) + (func $odd (export "odd") (param i32) (result i32) + (if (result i32) (i32.eqz (get_local 0)) + (then (i32.const 99)) + (else + (call_indirect (type $over-i32) + (i32.sub (get_local 0) (i32.const 1)) + (i32.const 14) + ) + ) + ) + ) + + ;; Stack exhaustion + + ;; Implementations are required to have every call consume some abstract + ;; resource towards exhausting some abstract finite limit, such that + ;; infinitely recursive test cases reliably trap in finite time. This is + ;; because otherwise applications could come to depend on it on those + ;; implementations and be incompatible with implementations that don't do + ;; it (or don't do it under the same circumstances). + + (func $runaway (export "runaway") (call_indirect (type $proc) (i32.const 16))) + + (func $mutual-runaway1 (export "mutual-runaway") (call_indirect (type $proc) (i32.const 18))) + (func $mutual-runaway2 (call_indirect (type $proc) (i32.const 17))) + + ;; As parameter of control constructs and instructions + + (memory 1) + + (func (export "as-select-first") (result i32) + (select (call_indirect (type $out-i32) (i32.const 0)) (i32.const 2) (i32.const 3)) + ) + (func (export "as-select-mid") (result i32) + (select (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (i32.const 3)) + ) + (func (export "as-select-last") (result i32) + (select (i32.const 2) (i32.const 3) (call_indirect (type $out-i32) (i32.const 0))) + ) + + (func (export "as-if-condition") (result i32) + (if (result i32) (call_indirect (type $out-i32) (i32.const 0)) (then (i32.const 1)) (else (i32.const 2))) + ) + + (func (export "as-br_if-first") (result i64) + (block (result i64) (br_if 0 (call_indirect (type $out-i64) (i32.const 1)) (i32.const 2))) + ) + (func (export "as-br_if-last") (result i32) + (block (result i32) (br_if 0 (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)))) + ) + + (func (export "as-br_table-first") (result f32) + (block (result f32) (call_indirect (type $out-f32) (i32.const 2)) (i32.const 2) (br_table 0 0)) + ) + (func (export "as-br_table-last") (result i32) + (block (result i32) (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (br_table 0 0)) + ) + + (func (export "as-store-first") + (call_indirect (type $out-i32) (i32.const 0)) (i32.const 1) (i32.store) + ) + (func (export "as-store-last") + (i32.const 10) (call_indirect (type $out-f64) (i32.const 3)) (f64.store) + ) + + (func (export "as-memory.grow-value") (result i32) + (memory.grow (call_indirect (type $out-i32) (i32.const 0))) + ) + (func (export "as-return-value") (result i32) + (call_indirect (type $over-i32) (i32.const 1) (i32.const 4)) (return) + ) + (func (export "as-drop-operand") + (call_indirect (type $over-i64) (i64.const 1) (i32.const 5)) (drop) + ) + (func (export "as-br-value") (result f32) + (block (result f32) (br 0 (call_indirect (type $over-f32) (f32.const 1) (i32.const 6)))) + ) + (func (export "as-set_local-value") (result f64) + (local f64) (set_local 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7))) (get_local 0) + ) + (func (export "as-load-operand") (result i32) + (i32.load (call_indirect (type $out-i32) (i32.const 0))) + ) +) + +(assert_return (invoke "type-i32") (i32.const 0x132)) +(assert_return (invoke "type-i64") (i64.const 0x164)) +(assert_return (invoke "type-f32") (f32.const 0xf32)) +(assert_return (invoke "type-f64") (f64.const 0xf64)) + +(assert_return (invoke "type-index") (i64.const 100)) + +(assert_return (invoke "type-first-i32") (i32.const 32)) +(assert_return (invoke "type-first-i64") (i64.const 64)) +(assert_return (invoke "type-first-f32") (f32.const 1.32)) +(assert_return (invoke "type-first-f64") (f64.const 1.64)) + +(assert_return (invoke "type-second-i32") (i32.const 32)) +(assert_return (invoke "type-second-i64") (i64.const 64)) +(assert_return (invoke "type-second-f32") (f32.const 32)) +(assert_return (invoke "type-second-f64") (f64.const 64.1)) + +(assert_return (invoke "dispatch" (i32.const 5) (i64.const 2)) (i64.const 2)) +(assert_return (invoke "dispatch" (i32.const 5) (i64.const 5)) (i64.const 5)) +(assert_return (invoke "dispatch" (i32.const 12) (i64.const 5)) (i64.const 120)) +(assert_return (invoke "dispatch" (i32.const 13) (i64.const 5)) (i64.const 8)) +(assert_return (invoke "dispatch" (i32.const 20) (i64.const 2)) (i64.const 2)) +(assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call type mismatch") +(assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call type mismatch") +(assert_trap (invoke "dispatch" (i32.const 29) (i64.const 2)) "undefined element") +(assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element") +(assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element") + +(assert_return (invoke "dispatch-structural-i64" (i32.const 5)) (i64.const 9)) +(assert_return (invoke "dispatch-structural-i64" (i32.const 12)) (i64.const 362880)) +(assert_return (invoke "dispatch-structural-i64" (i32.const 13)) (i64.const 55)) +(assert_return (invoke "dispatch-structural-i64" (i32.const 20)) (i64.const 9)) +(assert_trap (invoke "dispatch-structural-i64" (i32.const 11)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-i64" (i32.const 22)) "indirect call type mismatch") + +(assert_return (invoke "dispatch-structural-i32" (i32.const 4)) (i32.const 9)) +(assert_return (invoke "dispatch-structural-i32" (i32.const 23)) (i32.const 362880)) +(assert_return (invoke "dispatch-structural-i32" (i32.const 26)) (i32.const 55)) +(assert_return (invoke "dispatch-structural-i32" (i32.const 19)) (i32.const 9)) +(assert_trap (invoke "dispatch-structural-i32" (i32.const 9)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-i32" (i32.const 21)) "indirect call type mismatch") + +(assert_return (invoke "dispatch-structural-f32" (i32.const 6)) (f32.const 9.0)) +(assert_return (invoke "dispatch-structural-f32" (i32.const 24)) (f32.const 362880.0)) +(assert_return (invoke "dispatch-structural-f32" (i32.const 27)) (f32.const 55.0)) +(assert_return (invoke "dispatch-structural-f32" (i32.const 21)) (f32.const 9.0)) +(assert_trap (invoke "dispatch-structural-f32" (i32.const 8)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-f32" (i32.const 19)) "indirect call type mismatch") + +(assert_return (invoke "dispatch-structural-f64" (i32.const 7)) (f64.const 9.0)) +(assert_return (invoke "dispatch-structural-f64" (i32.const 25)) (f64.const 362880.0)) +(assert_return (invoke "dispatch-structural-f64" (i32.const 28)) (f64.const 55.0)) +(assert_return (invoke "dispatch-structural-f64" (i32.const 22)) (f64.const 9.0)) +(assert_trap (invoke "dispatch-structural-f64" (i32.const 10)) "indirect call type mismatch") +(assert_trap (invoke "dispatch-structural-f64" (i32.const 18)) "indirect call type mismatch") + +(assert_return (invoke "fac-i64" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "fac-i64" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "fac-i64" (i64.const 5)) (i64.const 120)) +(assert_return (invoke "fac-i64" (i64.const 25)) (i64.const 7034535277573963776)) + +(assert_return (invoke "fac-i32" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "fac-i32" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "fac-i32" (i32.const 5)) (i32.const 120)) +(assert_return (invoke "fac-i32" (i32.const 10)) (i32.const 3628800)) + +(assert_return (invoke "fac-f32" (f32.const 0.0)) (f32.const 1.0)) +(assert_return (invoke "fac-f32" (f32.const 1.0)) (f32.const 1.0)) +(assert_return (invoke "fac-f32" (f32.const 5.0)) (f32.const 120.0)) +(assert_return (invoke "fac-f32" (f32.const 10.0)) (f32.const 3628800.0)) + +(assert_return (invoke "fac-f64" (f64.const 0.0)) (f64.const 1.0)) +(assert_return (invoke "fac-f64" (f64.const 1.0)) (f64.const 1.0)) +(assert_return (invoke "fac-f64" (f64.const 5.0)) (f64.const 120.0)) +(assert_return (invoke "fac-f64" (f64.const 10.0)) (f64.const 3628800.0)) + +(assert_return (invoke "fib-i64" (i64.const 0)) (i64.const 1)) +(assert_return (invoke "fib-i64" (i64.const 1)) (i64.const 1)) +(assert_return (invoke "fib-i64" (i64.const 2)) (i64.const 2)) +(assert_return (invoke "fib-i64" (i64.const 5)) (i64.const 8)) +(assert_return (invoke "fib-i64" (i64.const 20)) (i64.const 10946)) + +(assert_return (invoke "fib-i32" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "fib-i32" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "fib-i32" (i32.const 2)) (i32.const 2)) +(assert_return (invoke "fib-i32" (i32.const 5)) (i32.const 8)) +(assert_return (invoke "fib-i32" (i32.const 20)) (i32.const 10946)) + +(assert_return (invoke "fib-f32" (f32.const 0.0)) (f32.const 1.0)) +(assert_return (invoke "fib-f32" (f32.const 1.0)) (f32.const 1.0)) +(assert_return (invoke "fib-f32" (f32.const 2.0)) (f32.const 2.0)) +(assert_return (invoke "fib-f32" (f32.const 5.0)) (f32.const 8.0)) +(assert_return (invoke "fib-f32" (f32.const 20.0)) (f32.const 10946.0)) + +(assert_return (invoke "fib-f64" (f64.const 0.0)) (f64.const 1.0)) +(assert_return (invoke "fib-f64" (f64.const 1.0)) (f64.const 1.0)) +(assert_return (invoke "fib-f64" (f64.const 2.0)) (f64.const 2.0)) +(assert_return (invoke "fib-f64" (f64.const 5.0)) (f64.const 8.0)) +(assert_return (invoke "fib-f64" (f64.const 20.0)) (f64.const 10946.0)) + +(assert_return (invoke "even" (i32.const 0)) (i32.const 44)) +(assert_return (invoke "even" (i32.const 1)) (i32.const 99)) +(assert_return (invoke "even" (i32.const 100)) (i32.const 44)) +(assert_return (invoke "even" (i32.const 77)) (i32.const 99)) +(assert_return (invoke "odd" (i32.const 0)) (i32.const 99)) +(assert_return (invoke "odd" (i32.const 1)) (i32.const 44)) +(assert_return (invoke "odd" (i32.const 200)) (i32.const 99)) +(assert_return (invoke "odd" (i32.const 77)) (i32.const 44)) + +(assert_exhaustion (invoke "runaway") "call stack exhausted") +(assert_exhaustion (invoke "mutual-runaway") "call stack exhausted") + +(assert_return (invoke "as-select-first") (i32.const 0x132)) +(assert_return (invoke "as-select-mid") (i32.const 2)) +(assert_return (invoke "as-select-last") (i32.const 2)) + +(assert_return (invoke "as-if-condition") (i32.const 1)) + +(assert_return (invoke "as-br_if-first") (i64.const 0x164)) +(assert_return (invoke "as-br_if-last") (i32.const 2)) + +(assert_return (invoke "as-br_table-first") (f32.const 0xf32)) +(assert_return (invoke "as-br_table-last") (i32.const 2)) + +;; (assert_return (invoke "as-store-first")) +;; (assert_return (invoke "as-store-last")) + +;; (assert_return (invoke "as-memory.grow-value") (i32.const 1)) +(assert_return (invoke "as-return-value") (i32.const 1)) +(assert_return (invoke "as-drop-operand")) +(assert_return (invoke "as-br-value") (f32.const 1)) +(assert_return (invoke "as-set_local-value") (f64.const 1)) +;; (assert_return (invoke "as-load-operand") (i32.const 1)) + +;; Invalid syntax + +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (param i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (param i32) (type $sig) (result i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (param i32) (result i32) (type $sig)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (type $sig) (param i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (param i32) (type $sig)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (param i32) (i32.const 0) (i32.const 0))" + ")" + ) + "unexpected token" +) + +(assert_malformed + (module quote + "(table 0 anyfunc)" + "(func (call_indirect (param $x i32) (i32.const 0) (i32.const 0)))" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func" + " (call_indirect (type $sig) (param i32) (i32.const 0) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32 i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (param i32) (result i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "inline function type" +) + +;; Invalid typing + +(assert_invalid + (module + (type (func)) + (func $no-table (call_indirect (type 0) (i32.const 0))) + ) + "unknown table" +) + +(assert_invalid + (module + (type (func)) + (table 0 anyfunc) + (func $type-void-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0)))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (result i64))) + (table 0 anyfunc) + (func $type-num-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0)))) + ) + "type mismatch" +) + +(assert_invalid + (module + (type (func (param i32))) + (table 0 anyfunc) + (func $arity-0-vs-1 (call_indirect (type 0) (i32.const 0))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param f64 i32))) + (table 0 anyfunc) + (func $arity-0-vs-2 (call_indirect (type 0) (i32.const 0))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func)) + (table 0 anyfunc) + (func $arity-1-vs-0 (call_indirect (type 0) (i32.const 1) (i32.const 0))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func)) + (table 0 anyfunc) + (func $arity-2-vs-0 + (call_indirect (type 0) (f64.const 2) (i32.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) + +(assert_invalid + (module + (type (func (param i32))) + (table 0 anyfunc) + (func $type-func-void-vs-i32 (call_indirect (type 0) (i32.const 1) (nop))) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param i32))) + (table 0 anyfunc) + (func $type-func-num-vs-i32 (call_indirect (type 0) (i32.const 0) (i64.const 1))) + ) + "type mismatch" +) + +(assert_invalid + (module + (type (func (param i32 i32))) + (table 0 anyfunc) + (func $type-first-void-vs-num + (call_indirect (type 0) (nop) (i32.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param i32 i32))) + (table 0 anyfunc) + (func $type-second-void-vs-num + (call_indirect (type 0) (i32.const 1) (nop) (i32.const 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param i32 f64))) + (table 0 anyfunc) + (func $type-first-num-vs-num + (call_indirect (type 0) (f64.const 1) (i32.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type (func (param f64 i32))) + (table 0 anyfunc) + (func $type-second-num-vs-num + (call_indirect (type 0) (i32.const 1) (f64.const 1) (i32.const 0)) + ) + ) + "type mismatch" +) + + +;; Unbound type + +(assert_invalid + (module + (table 0 anyfunc) + (func $unbound-type (call_indirect (type 1) (i32.const 0))) + ) + "unknown type" +) +(assert_invalid + (module + (table 0 anyfunc) + (func $large-type (call_indirect (type 1012321300) (i32.const 0))) + ) + "unknown type" +) + + +;; Unbound function in table + +(assert_invalid + (module (table anyfunc (elem 0 0))) + "unknown function 0" +) diff --git a/src/build_spectests.rs b/src/build_spectests.rs index e2860f107ea..7a55f6de23b 100644 --- a/src/build_spectests.rs +++ b/src/build_spectests.rs @@ -8,9 +8,10 @@ use wabt::wasm2wat; static BANNER: &str = "// Rust test file autogenerated with cargo build (src/build_spectests.rs). // Please do NOT modify it by hand, as it will be reseted on next build.\n"; -const TESTS: [&str; 6] = [ +const TESTS: [&str; 7] = [ "spectests/br_if.wast", "spectests/call.wast", + "spectests/call_indirect.wast", "spectests/i32_.wast", "spectests/memory.wast", "spectests/set_local.wast", diff --git a/src/common/slice.rs b/src/common/slice.rs index 06a297c4375..f104edf49a5 100644 --- a/src/common/slice.rs +++ b/src/common/slice.rs @@ -1,5 +1,5 @@ -use core::ops::{Index, IndexMut}; -use core::ptr::NonNull; +use std::ops::{Index, IndexMut}; +use std::ptr::NonNull; #[derive(Copy, Clone)] #[repr(transparent)] diff --git a/src/integrations/mod.rs b/src/integrations/mod.rs index 857b27bded5..f0d2436f1f2 100644 --- a/src/integrations/mod.rs +++ b/src/integrations/mod.rs @@ -1,4 +1,4 @@ -use crate::webassembly::ImportObject; +use crate::webassembly::{ImportObject, VmCtx}; use libc::putchar; pub fn generate_libc_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { @@ -11,7 +11,7 @@ pub fn generate_libc_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { mod tests { use super::generate_libc_env; use crate::webassembly::{ - instantiate, ErrorKind, Export, ImportObject, Instance, Module, ResultObject, + instantiate, ErrorKind, Export, ImportObject, Instance, Module, ResultObject, VmCtx, }; use libc::putchar; @@ -21,12 +21,13 @@ mod tests { let import_object = generate_libc_env(); let result_object = instantiate(wasm_bytes, import_object).expect("Not compiled properly"); let module = result_object.module; - let instance = result_object.instance; + let mut instance = result_object.instance; let func_index = match module.info.exports.get("main") { Some(&Export::Function(index)) => index, _ => panic!("Function not found"), }; - let main: fn() = get_instance_function!(instance, func_index); - main(); + let main: fn(&VmCtx) = get_instance_function!(instance, func_index); + let context = instance.generate_context(); + main(&context); } } diff --git a/src/main.rs b/src/main.rs index b67c4fc64c5..492d31d48d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,12 @@ extern crate wabt; extern crate target_lexicon; extern crate spin; +use std::alloc::System; use std::time::{Duration, Instant}; +// #[global_allocator] +// static A: System = System; + // #[macro_use] extern crate log; use libc; @@ -71,17 +75,21 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { } let import_object = integrations::generate_libc_env(); - let webassembly::ResultObject { module, instance } = - webassembly::instantiate(wasm_binary, import_object) - .map_err(|err| String::from(err.description()))?; + let webassembly::ResultObject { + module, + mut instance, + } = webassembly::instantiate(wasm_binary, import_object) + .map_err(|err| String::from(err.description()))?; let func_index = instance .start_func .unwrap_or_else(|| match module.info.exports.get("main") { Some(&webassembly::Export::Function(index)) => index, _ => panic!("Main function not found"), }); - let main: fn() = get_instance_function!(instance, func_index); - main(); + let main: fn(&webassembly::VmCtx) -> i32 = get_instance_function!(instance, func_index); + let context = instance.generate_context(); + let result = main(&context); + println!("RESULT {}", result); Ok(()) } diff --git a/src/spectests/call_indirect.rs b/src/spectests/call_indirect.rs new file mode 100644 index 00000000000..4a6f0dce4b9 --- /dev/null +++ b/src/spectests/call_indirect.rs @@ -0,0 +1,2028 @@ +// Rust test file autogenerated with cargo build (src/build_spectests.rs). +// Please do NOT modify it by hand, as it will be reseted on next build. +// Test based on spectests/call_indirect.wast + +use crate::webassembly::{instantiate, compile, ImportObject, ResultObject, VmCtx, Export}; +use wabt::wat2wasm; + + +// Line 3 +fn create_module_1() -> ResultObject { + let module_str = "(module + (type (;0;) (func)) + (type (;1;) (func (result i32))) + (type (;2;) (func (result i64))) + (type (;3;) (func (result f32))) + (type (;4;) (func (result f64))) + (type (;5;) (func (param i32) (result i32))) + (type (;6;) (func (param i64) (result i64))) + (type (;7;) (func (param f32) (result f32))) + (type (;8;) (func (param f64) (result f64))) + (type (;9;) (func (param f32 i32) (result i32))) + (type (;10;) (func (param i32 i64) (result i64))) + (type (;11;) (func (param f64 f32) (result f32))) + (type (;12;) (func (param i64 f64) (result f64))) + (type (;13;) (func (param i32) (result i32))) + (type (;14;) (func (param i64) (result i64))) + (type (;15;) (func (param f32) (result f32))) + (type (;16;) (func (param f64) (result f64))) + (type (;17;) (func (param i64))) + (type (;18;) (func (param i64 f64 i32 i64))) + (type (;19;) (func (param i64) (result i32))) + (type (;20;) (func (param i64 f64 i32 i64) (result i32))) + (type (;21;) (func (param i32) (result i64))) + (type (;22;) (func (param i32) (result f32))) + (type (;23;) (func (param i32) (result f64))) + (func (;0;) (type 1) (result i32) + i32.const 306) + (func (;1;) (type 2) (result i64) + i64.const 356) + (func (;2;) (type 3) (result f32) + f32.const 0x1.e64p+11 (;=3890;)) + (func (;3;) (type 4) (result f64) + f64.const 0x1.ec8p+11 (;=3940;)) + (func (;4;) (type 5) (param i32) (result i32) + get_local 0) + (func (;5;) (type 6) (param i64) (result i64) + get_local 0) + (func (;6;) (type 7) (param f32) (result f32) + get_local 0) + (func (;7;) (type 8) (param f64) (result f64) + get_local 0) + (func (;8;) (type 10) (param i32 i64) (result i64) + get_local 1) + (func (;9;) (type 12) (param i64 f64) (result f64) + get_local 1) + (func (;10;) (type 9) (param f32 i32) (result i32) + get_local 1) + (func (;11;) (type 11) (param f64 f32) (result f32) + get_local 1) + (func (;12;) (type 13) (param i32) (result i32) + get_local 0) + (func (;13;) (type 14) (param i64) (result i64) + get_local 0) + (func (;14;) (type 15) (param f32) (result f32) + get_local 0) + (func (;15;) (type 16) (param f64) (result f64) + get_local 0) + (func (;16;) (type 0) + i32.const 0 + call_indirect (type 0) + i64.const 0 + i32.const 0 + call_indirect (type 17) + i64.const 0 + f64.const 0x0p+0 (;=0;) + i32.const 0 + i64.const 0 + i32.const 0 + call_indirect (type 18) + i32.const 0 + call_indirect (type 0) + i32.const 0 + call_indirect (type 1) + i32.eqz + drop + i32.const 0 + call_indirect (type 1) + i32.eqz + drop + i64.const 0 + i32.const 0 + call_indirect (type 19) + i32.eqz + drop + i64.const 0 + f64.const 0x0p+0 (;=0;) + i32.const 0 + i64.const 0 + i32.const 0 + call_indirect (type 20) + i32.eqz + drop + i64.const 0 + i32.const 0 + call_indirect (type 6) + i64.eqz + drop) + (func (;17;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1)) + (func (;18;) (type 2) (result i64) + i32.const 1 + call_indirect (type 2)) + (func (;19;) (type 3) (result f32) + i32.const 2 + call_indirect (type 3)) + (func (;20;) (type 4) (result f64) + i32.const 3 + call_indirect (type 4)) + (func (;21;) (type 2) (result i64) + i64.const 100 + i32.const 5 + call_indirect (type 6)) + (func (;22;) (type 1) (result i32) + i32.const 32 + i32.const 4 + call_indirect (type 5)) + (func (;23;) (type 2) (result i64) + i64.const 64 + i32.const 5 + call_indirect (type 6)) + (func (;24;) (type 3) (result f32) + f32.const 0x1.51eb86p+0 (;=1.32;) + i32.const 6 + call_indirect (type 7)) + (func (;25;) (type 4) (result f64) + f64.const 0x1.a3d70a3d70a3dp+0 (;=1.64;) + i32.const 7 + call_indirect (type 8)) + (func (;26;) (type 1) (result i32) + f32.const 0x1.00ccccp+5 (;=32.1;) + i32.const 32 + i32.const 8 + call_indirect (type 9)) + (func (;27;) (type 2) (result i64) + i32.const 32 + i64.const 64 + i32.const 9 + call_indirect (type 10)) + (func (;28;) (type 3) (result f32) + f64.const 0x1p+6 (;=64;) + f32.const 0x1p+5 (;=32;) + i32.const 10 + call_indirect (type 11)) + (func (;29;) (type 4) (result f64) + i64.const 64 + f64.const 0x1.0066666666666p+6 (;=64.1;) + i32.const 11 + call_indirect (type 12)) + (func (;30;) (type 10) (param i32 i64) (result i64) + get_local 1 + get_local 0 + call_indirect (type 6)) + (func (;31;) (type 21) (param i32) (result i64) + i64.const 9 + get_local 0 + call_indirect (type 14)) + (func (;32;) (type 5) (param i32) (result i32) + i32.const 9 + get_local 0 + call_indirect (type 13)) + (func (;33;) (type 22) (param i32) (result f32) + f32.const 0x1.2p+3 (;=9;) + get_local 0 + call_indirect (type 15)) + (func (;34;) (type 23) (param i32) (result f64) + f64.const 0x1.2p+3 (;=9;) + get_local 0 + call_indirect (type 16)) + (func (;35;) (type 6) (param i64) (result i64) + get_local 0 + i64.eqz + if (result i64) ;; label = @1 + i64.const 1 + else + get_local 0 + get_local 0 + i64.const 1 + i64.sub + i32.const 12 + call_indirect (type 6) + i64.mul + end) + (func (;36;) (type 6) (param i64) (result i64) + get_local 0 + i64.const 1 + i64.le_u + if (result i64) ;; label = @1 + i64.const 1 + else + get_local 0 + i64.const 2 + i64.sub + i32.const 13 + call_indirect (type 6) + get_local 0 + i64.const 1 + i64.sub + i32.const 13 + call_indirect (type 6) + i64.add + end) + (func (;37;) (type 5) (param i32) (result i32) + get_local 0 + i32.eqz + if (result i32) ;; label = @1 + i32.const 1 + else + get_local 0 + get_local 0 + i32.const 1 + i32.sub + i32.const 23 + call_indirect (type 5) + i32.mul + end) + (func (;38;) (type 7) (param f32) (result f32) + get_local 0 + f32.const 0x0p+0 (;=0;) + f32.eq + if (result f32) ;; label = @1 + f32.const 0x1p+0 (;=1;) + else + get_local 0 + get_local 0 + f32.const 0x1p+0 (;=1;) + f32.sub + i32.const 24 + call_indirect (type 7) + f32.mul + end) + (func (;39;) (type 8) (param f64) (result f64) + get_local 0 + f64.const 0x0p+0 (;=0;) + f64.eq + if (result f64) ;; label = @1 + f64.const 0x1p+0 (;=1;) + else + get_local 0 + get_local 0 + f64.const 0x1p+0 (;=1;) + f64.sub + i32.const 25 + call_indirect (type 8) + f64.mul + end) + (func (;40;) (type 5) (param i32) (result i32) + get_local 0 + i32.const 1 + i32.le_u + if (result i32) ;; label = @1 + i32.const 1 + else + get_local 0 + i32.const 2 + i32.sub + i32.const 26 + call_indirect (type 5) + get_local 0 + i32.const 1 + i32.sub + i32.const 26 + call_indirect (type 5) + i32.add + end) + (func (;41;) (type 7) (param f32) (result f32) + get_local 0 + f32.const 0x1p+0 (;=1;) + f32.le + if (result f32) ;; label = @1 + f32.const 0x1p+0 (;=1;) + else + get_local 0 + f32.const 0x1p+1 (;=2;) + f32.sub + i32.const 27 + call_indirect (type 7) + get_local 0 + f32.const 0x1p+0 (;=1;) + f32.sub + i32.const 27 + call_indirect (type 7) + f32.add + end) + (func (;42;) (type 8) (param f64) (result f64) + get_local 0 + f64.const 0x1p+0 (;=1;) + f64.le + if (result f64) ;; label = @1 + f64.const 0x1p+0 (;=1;) + else + get_local 0 + f64.const 0x1p+1 (;=2;) + f64.sub + i32.const 28 + call_indirect (type 8) + get_local 0 + f64.const 0x1p+0 (;=1;) + f64.sub + i32.const 28 + call_indirect (type 8) + f64.add + end) + (func (;43;) (type 5) (param i32) (result i32) + get_local 0 + i32.eqz + if (result i32) ;; label = @1 + i32.const 44 + else + get_local 0 + i32.const 1 + i32.sub + i32.const 15 + call_indirect (type 5) + end) + (func (;44;) (type 5) (param i32) (result i32) + get_local 0 + i32.eqz + if (result i32) ;; label = @1 + i32.const 99 + else + get_local 0 + i32.const 1 + i32.sub + i32.const 14 + call_indirect (type 5) + end) + (func (;45;) (type 0) + i32.const 16 + call_indirect (type 0)) + (func (;46;) (type 0) + i32.const 18 + call_indirect (type 0)) + (func (;47;) (type 0) + i32.const 17 + call_indirect (type 0)) + (func (;48;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + i32.const 2 + i32.const 3 + select) + (func (;49;) (type 1) (result i32) + i32.const 2 + i32.const 0 + call_indirect (type 1) + i32.const 3 + select) + (func (;50;) (type 1) (result i32) + i32.const 2 + i32.const 3 + i32.const 0 + call_indirect (type 1) + select) + (func (;51;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + if (result i32) ;; label = @1 + i32.const 1 + else + i32.const 2 + end) + (func (;52;) (type 2) (result i64) + block (result i64) ;; label = @1 + i32.const 1 + call_indirect (type 2) + i32.const 2 + br_if 0 (;@1;) + end) + (func (;53;) (type 1) (result i32) + block (result i32) ;; label = @1 + i32.const 2 + i32.const 0 + call_indirect (type 1) + br_if 0 (;@1;) + end) + (func (;54;) (type 3) (result f32) + block (result f32) ;; label = @1 + i32.const 2 + call_indirect (type 3) + i32.const 2 + br_table 0 (;@1;) 0 (;@1;) + end) + (func (;55;) (type 1) (result i32) + block (result i32) ;; label = @1 + i32.const 2 + i32.const 0 + call_indirect (type 1) + br_table 0 (;@1;) 0 (;@1;) + end) + (func (;56;) (type 0) + i32.const 0 + call_indirect (type 1) + i32.const 1 + i32.store) + (func (;57;) (type 0) + i32.const 10 + i32.const 3 + call_indirect (type 4) + f64.store) + (func (;58;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + memory.grow) + (func (;59;) (type 1) (result i32) + i32.const 1 + i32.const 4 + call_indirect (type 5) + return) + (func (;60;) (type 0) + i64.const 1 + i32.const 5 + call_indirect (type 6) + drop) + (func (;61;) (type 3) (result f32) + block (result f32) ;; label = @1 + f32.const 0x1p+0 (;=1;) + i32.const 6 + call_indirect (type 7) + br 0 (;@1;) + end) + (func (;62;) (type 4) (result f64) + (local f64) + f64.const 0x1p+0 (;=1;) + i32.const 7 + call_indirect (type 8) + set_local 0 + get_local 0) + (func (;63;) (type 1) (result i32) + i32.const 0 + call_indirect (type 1) + i32.load) + (table (;0;) 29 29 anyfunc) + (memory (;0;) 1) + (export \"type-i32\" (func 17)) + (export \"type-i64\" (func 18)) + (export \"type-f32\" (func 19)) + (export \"type-f64\" (func 20)) + (export \"type-index\" (func 21)) + (export \"type-first-i32\" (func 22)) + (export \"type-first-i64\" (func 23)) + (export \"type-first-f32\" (func 24)) + (export \"type-first-f64\" (func 25)) + (export \"type-second-i32\" (func 26)) + (export \"type-second-i64\" (func 27)) + (export \"type-second-f32\" (func 28)) + (export \"type-second-f64\" (func 29)) + (export \"dispatch\" (func 30)) + (export \"dispatch-structural-i64\" (func 31)) + (export \"dispatch-structural-i32\" (func 32)) + (export \"dispatch-structural-f32\" (func 33)) + (export \"dispatch-structural-f64\" (func 34)) + (export \"fac-i64\" (func 35)) + (export \"fib-i64\" (func 36)) + (export \"fac-i32\" (func 37)) + (export \"fac-f32\" (func 38)) + (export \"fac-f64\" (func 39)) + (export \"fib-i32\" (func 40)) + (export \"fib-f32\" (func 41)) + (export \"fib-f64\" (func 42)) + (export \"even\" (func 43)) + (export \"odd\" (func 44)) + (export \"runaway\" (func 45)) + (export \"mutual-runaway\" (func 46)) + (export \"as-select-first\" (func 48)) + (export \"as-select-mid\" (func 49)) + (export \"as-select-last\" (func 50)) + (export \"as-if-condition\" (func 51)) + (export \"as-br_if-first\" (func 52)) + (export \"as-br_if-last\" (func 53)) + (export \"as-br_table-first\" (func 54)) + (export \"as-br_table-last\" (func 55)) + (export \"as-store-first\" (func 56)) + (export \"as-store-last\" (func 57)) + (export \"as-memory.grow-value\" (func 58)) + (export \"as-return-value\" (func 59)) + (export \"as-drop-operand\" (func 60)) + (export \"as-br-value\" (func 61)) + (export \"as-set_local-value\" (func 62)) + (export \"as-load-operand\" (func 63)) + (elem (i32.const 0) 0 1 2 3 4 5 6 7 10 8 11 9 35 36 43 44 45 46 47 12 13 14 15 37 38 39 40 41 42)) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, ImportObject::new()).expect("WASM can't be instantiated") +} + +// Line 379 +#[test] +fn l379_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 306 as i32); +} + +// Line 380 +#[test] +fn l380_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 356 as i64); +} + +// Line 381 +#[test] +fn l381_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 3890.0 as f32); +} + +// Line 382 +#[test] +fn l382_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 3940.0 as f64); +} + +// Line 384 +#[test] +fn l384_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-index") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 100 as i64); +} + +// Line 386 +#[test] +fn l386_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 32 as i32); +} + +// Line 387 +#[test] +fn l387_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 64 as i64); +} + +// Line 388 +#[test] +fn l388_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.32 as f32); +} + +// Line 389 +#[test] +fn l389_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-first-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.64 as f64); +} + +// Line 391 +#[test] +fn l391_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 32 as i32); +} + +// Line 392 +#[test] +fn l392_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 64 as i64); +} + +// Line 393 +#[test] +fn l393_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 32.0 as f32); +} + +// Line 394 +#[test] +fn l394_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("type-second-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 64.1 as f64); +} + +// Line 396 +#[test] +fn l396_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, 2 as i64, &vm_context); + assert_eq!(result, 2 as i64); +} + +// Line 397 +#[test] +fn l397_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, 5 as i64, &vm_context); + assert_eq!(result, 5 as i64); +} + +// Line 398 +#[test] +fn l398_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(12 as i32, 5 as i64, &vm_context); + assert_eq!(result, 120 as i64); +} + +// Line 399 +#[test] +fn l399_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(13 as i32, 5 as i64, &vm_context); + assert_eq!(result, 8 as i64); +} + +// Line 400 +#[test] +fn l400_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i32, 2 as i64, &vm_context); + assert_eq!(result, 2 as i64); +} + +// Line 401 + +// Line 402 + +// Line 403 + +// Line 404 + +// Line 405 + +// Line 407 +#[test] +fn l407_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, &vm_context); + assert_eq!(result, 9 as i64); +} + +// Line 408 +#[test] +fn l408_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(12 as i32, &vm_context); + assert_eq!(result, 362880 as i64); +} + +// Line 409 +#[test] +fn l409_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(13 as i32, &vm_context); + assert_eq!(result, 55 as i64); +} + +// Line 410 +#[test] +fn l410_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i32, &vm_context); + assert_eq!(result, 9 as i64); +} + +// Line 411 + +// Line 412 + +// Line 414 +#[test] +fn l414_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(4 as i32, &vm_context); + assert_eq!(result, 9 as i32); +} + +// Line 415 +#[test] +fn l415_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(23 as i32, &vm_context); + assert_eq!(result, 362880 as i32); +} + +// Line 416 +#[test] +fn l416_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(26 as i32, &vm_context); + assert_eq!(result, 55 as i32); +} + +// Line 417 +#[test] +fn l417_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(19 as i32, &vm_context); + assert_eq!(result, 9 as i32); +} + +// Line 418 + +// Line 419 + +// Line 421 +#[test] +fn l421_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(6 as i32, &vm_context); + assert_eq!(result, 9.0 as f32); +} + +// Line 422 +#[test] +fn l422_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(24 as i32, &vm_context); + assert_eq!(result, 362880.0 as f32); +} + +// Line 423 +#[test] +fn l423_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(27 as i32, &vm_context); + assert_eq!(result, 55.0 as f32); +} + +// Line 424 +#[test] +fn l424_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(21 as i32, &vm_context); + assert_eq!(result, 9.0 as f32); +} + +// Line 425 + +// Line 426 + +// Line 428 +#[test] +fn l428_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(7 as i32, &vm_context); + assert_eq!(result, 9.0 as f64); +} + +// Line 429 +#[test] +fn l429_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(25 as i32, &vm_context); + assert_eq!(result, 362880.0 as f64); +} + +// Line 430 +#[test] +fn l430_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(28 as i32, &vm_context); + assert_eq!(result, 55.0 as f64); +} + +// Line 431 +#[test] +fn l431_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("dispatch-structural-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(22 as i32, &vm_context); + assert_eq!(result, 9.0 as f64); +} + +// Line 432 + +// Line 433 + +// Line 435 +#[test] +fn l435_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 436 +#[test] +fn l436_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 437 +#[test] +fn l437_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i64, &vm_context); + assert_eq!(result, 120 as i64); +} + +// Line 438 +#[test] +fn l438_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(25 as i64, &vm_context); + assert_eq!(result, 7034535277573963776 as i64); +} + +// Line 440 +#[test] +fn l440_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 441 +#[test] +fn l441_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 442 +#[test] +fn l442_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, &vm_context); + assert_eq!(result, 120 as i32); +} + +// Line 443 +#[test] +fn l443_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(10 as i32, &vm_context); + assert_eq!(result, 3628800 as i32); +} + +// Line 445 +#[test] +fn l445_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 446 +#[test] +fn l446_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 447 +#[test] +fn l447_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f32, &vm_context); + assert_eq!(result, 120.0 as f32); +} + +// Line 448 +#[test] +fn l448_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(10.0 as f32, &vm_context); + assert_eq!(result, 3628800.0 as f32); +} + +// Line 450 +#[test] +fn l450_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 451 +#[test] +fn l451_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 452 +#[test] +fn l452_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f64, &vm_context); + assert_eq!(result, 120.0 as f64); +} + +// Line 453 +#[test] +fn l453_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fac-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(10.0 as f64, &vm_context); + assert_eq!(result, 3628800.0 as f64); +} + +// Line 455 +#[test] +fn l455_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 456 +#[test] +fn l456_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i64, &vm_context); + assert_eq!(result, 1 as i64); +} + +// Line 457 +#[test] +fn l457_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2 as i64, &vm_context); + assert_eq!(result, 2 as i64); +} + +// Line 458 +#[test] +fn l458_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i64, &vm_context); + assert_eq!(result, 8 as i64); +} + +// Line 459 +#[test] +fn l459_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i64, &VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i64, &vm_context); + assert_eq!(result, 10946 as i64); +} + +// Line 461 +#[test] +fn l461_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 462 +#[test] +fn l462_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 463 +#[test] +fn l463_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2 as i32, &vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 464 +#[test] +fn l464_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5 as i32, &vm_context); + assert_eq!(result, 8 as i32); +} + +// Line 465 +#[test] +fn l465_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-i32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20 as i32, &vm_context); + assert_eq!(result, 10946 as i32); +} + +// Line 467 +#[test] +fn l467_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 468 +#[test] +fn l468_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f32, &vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 469 +#[test] +fn l469_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2.0 as f32, &vm_context); + assert_eq!(result, 2.0 as f32); +} + +// Line 470 +#[test] +fn l470_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f32, &vm_context); + assert_eq!(result, 8.0 as f32); +} + +// Line 471 +#[test] +fn l471_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f32") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f32, &VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20.0 as f32, &vm_context); + assert_eq!(result, 10946.0 as f32); +} + +// Line 473 +#[test] +fn l473_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 474 +#[test] +fn l474_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1.0 as f64, &vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 475 +#[test] +fn l475_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(2.0 as f64, &vm_context); + assert_eq!(result, 2.0 as f64); +} + +// Line 476 +#[test] +fn l476_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(5.0 as f64, &vm_context); + assert_eq!(result, 8.0 as f64); +} + +// Line 477 +#[test] +fn l477_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("fib-f64") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(f64, &VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(20.0 as f64, &vm_context); + assert_eq!(result, 10946.0 as f64); +} + +// Line 479 +#[test] +fn l479_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 480 +#[test] +fn l480_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 481 +#[test] +fn l481_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(100 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 482 +#[test] +fn l482_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("even") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(77 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 483 +#[test] +fn l483_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(0 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 484 +#[test] +fn l484_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(1 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 485 +#[test] +fn l485_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(200 as i32, &vm_context); + assert_eq!(result, 99 as i32); +} + +// Line 486 +#[test] +fn l486_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("odd") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(i32, &VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(77 as i32, &vm_context); + assert_eq!(result, 44 as i32); +} + +// Line 488 + +// Line 489 + +// Line 491 +#[test] +fn l491_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-select-first") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 306 as i32); +} + +// Line 492 +#[test] +fn l492_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-select-mid") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 493 +#[test] +fn l493_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-select-last") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 495 +#[test] +fn l495_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-if-condition") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 497 +#[test] +fn l497_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_if-first") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 356 as i64); +} + +// Line 498 +#[test] +fn l498_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_if-last") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 500 +#[test] +fn l500_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_table-first") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 3890.0 as f32); +} + +// Line 501 +#[test] +fn l501_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br_table-last") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 2 as i32); +} + +// Line 507 +#[test] +fn l507_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-return-value") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> i32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1 as i32); +} + +// Line 508 +#[test] +fn l508_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-drop-operand") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, ()); +} + +// Line 509 +#[test] +fn l509_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-br-value") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f32 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.0 as f32); +} + +// Line 510 +#[test] +fn l510_assert_return_invoke() { + let ResultObject { mut instance, module } = create_module_1(); + let func_index = match module.info.exports.get("as-set_local-value") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&VmCtx) -> f64 = get_instance_function!(instance, func_index); + let vm_context = instance.generate_context(); + let result = invoke_fn(&vm_context); + assert_eq!(result, 1.0 as f64); +} + +// Line 516 + +#[test] +fn l516_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 528 + +#[test] +fn l528_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 540 + +#[test] +fn l540_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 552 + +#[test] +fn l552_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 564 + +#[test] +fn l564_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 576 + +#[test] +fn l576_assert_malformed() { + let wasm_binary = [40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 586 + +#[test] +fn l586_assert_malformed() { + let wasm_binary = [40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 112, 97, 114, 97, 109, 32, 36, 120, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 593 + +#[test] +fn l593_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 603 + +#[test] +fn l603_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 613 + +#[test] +fn l613_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 623 + +#[test] +fn l623_assert_malformed() { + let wasm_binary = [40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 40, 116, 97, 98, 108, 101, 32, 48, 32, 97, 110, 121, 102, 117, 110, 99, 41, 40, 102, 117, 110, 99, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 40, 99, 97, 108, 108, 95, 105, 110, 100, 105, 114, 101, 99, 116, 32, 40, 116, 121, 112, 101, 32, 36, 115, 105, 103, 41, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 32, 32, 41, 41]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 638 + +#[test] +fn l638_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 10, 9, 1, 7, 0, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 646 + +#[test] +fn l646_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 10, 1, 8, 0, 65, 0, 17, 0, 0, 69, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 654 + +#[test] +fn l654_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 0, 1, 126, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 10, 1, 8, 0, 65, 0, 17, 0, 0, 69, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 663 + +#[test] +fn l663_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 9, 1, 7, 0, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 671 + +#[test] +fn l671_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 124, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 9, 1, 7, 0, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 679 + +#[test] +fn l679_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 11, 1, 9, 0, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 687 + +#[test] +fn l687_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 20, 1, 18, 0, 68, 0, 0, 0, 0, 0, 0, 0, 64, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 698 + +#[test] +fn l698_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 10, 1, 8, 0, 65, 1, 1, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 706 + +#[test] +fn l706_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 11, 1, 9, 0, 65, 0, 66, 1, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 715 + +#[test] +fn l715_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 12, 1, 10, 0, 1, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 725 + +#[test] +fn l725_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 12, 1, 10, 0, 65, 1, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 735 + +#[test] +fn l735_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 124, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 20, 1, 18, 0, 68, 0, 0, 0, 0, 0, 0, 240, 63, 65, 1, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 745 + +#[test] +fn l745_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 124, 127, 0, 96, 0, 0, 3, 2, 1, 1, 4, 4, 1, 112, 0, 0, 10, 20, 1, 18, 0, 65, 1, 68, 0, 0, 0, 0, 0, 0, 240, 63, 65, 0, 17, 0, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 759 + +#[test] +fn l759_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 9, 1, 7, 0, 65, 0, 17, 1, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 766 + +#[test] +fn l766_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 4, 4, 1, 112, 0, 0, 10, 13, 1, 11, 0, 65, 0, 17, 148, 152, 219, 226, 3, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 777 + +#[test] +fn l777_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 5, 1, 112, 1, 2, 2, 9, 8, 1, 0, 65, 0, 11, 2, 0, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} diff --git a/src/spectests/mod.rs b/src/spectests/mod.rs index fb5eefd3234..6cab11e17d7 100644 --- a/src/spectests/mod.rs +++ b/src/spectests/mod.rs @@ -3,6 +3,7 @@ mod br_if; mod call; +mod call_indirect; mod i32_; mod memory; mod set_local; diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 4b82d3ee536..24b9936e247 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -68,39 +68,21 @@ fn get_function_addr( // (base as usize + offset) as _ // } -/// Zero-sized, non-instantiable type. -#[derive(Debug)] -pub enum VmCtx {} - -impl VmCtx { - pub fn data(&self) -> &VmCtxData { - let heap_ptr = self as *const _ as *const VmCtxData; - unsafe { &*heap_ptr.sub(1) } - } - - /// This is safe because the offset is 32 bits and thus - /// cannot extend out of the guarded wasm memory. - pub fn fastpath_offset_ptr(&self, offset: u32) -> *const T { - let heap_ptr = self as *const _ as *const u8; - unsafe { heap_ptr.add(offset as usize) as *const T } - } -} - -#[derive(Debug)] -#[repr(C)] -pub struct VmCtxData<'phantom> { +// #[derive(Debug)] +#[repr(C, packed)] +pub struct VmCtx<'phantom> { pub user_data: UserData, - // globals: UncheckedSlice, - // memories: UncheckedSlice>, - // tables: UncheckedSlice>, - globals: Vec, - memories: Vec>, - tables: Vec>, + globals: UncheckedSlice, + memories: UncheckedSlice>, + tables: UncheckedSlice>, + // globals: Vec, + // memories: Vec>, + // pub tables: Vec>, phantom: PhantomData<&'phantom ()>, } -#[derive(Debug)] -#[repr(C)] +// #[derive(Debug)] +#[repr(C, packed)] pub struct UserData { // pub process: Dispatch, pub instance: Instance, @@ -240,9 +222,13 @@ impl Instance { }, RelocationType::CurrentMemory => { current_memory as isize + // panic!("current memory not yet implemented"); + // unimplemented!() }, RelocationType::GrowMemory => { grow_memory as isize + // panic!("Grow memory not yet implemented"); + // unimplemented!() }, _ => unimplemented!() // RelocationType::Intrinsic(name) => { @@ -518,33 +504,35 @@ impl Instance { } } - pub fn generate_context(&mut self) -> &VmCtx { - let mut memories: Vec> = self.memories.iter().map(|mem| mem[..].into()).collect(); + pub fn generate_context(&mut self) -> VmCtx { + let memories: Vec> = + self.memories.iter().map(|mem| mem[..].into()).collect(); + let tables: Vec> = + self.tables.iter().map(|table| table[..].into()).collect(); + let globals: UncheckedSlice = self.globals[..].into(); - let tables: Vec> = self.tables.iter().map(|table| table[..].into()).collect(); + // println!("GENERATING CONTEXT {:?}", self.tables); - let globals: Vec = self.globals[..].into(); - - assert!(memories.len() >= 1, "modules must have at least one memory"); + // assert!(memories.len() >= 1, "modules must have at least one memory"); // the first memory has a space of `mem::size_of::()` rounded // up to the 4KiB before it. We write the VmCtxData into that. let instance = self.clone(); - let data = VmCtxData { + let data = VmCtx { globals: globals, - memories: memories[1..].into(), + memories: memories[..].into(), tables: tables[..].into(), user_data: UserData { // process, - instance, + instance: instance, }, phantom: PhantomData, }; - - let main_heap_ptr = memories[0].as_mut_ptr() as *mut VmCtxData; - unsafe { - main_heap_ptr.sub(1).write(data); - &*(main_heap_ptr as *const VmCtx) - } + data + // let main_heap_ptr = memories[0].as_mut_ptr() as *mut VmCtxData; + // unsafe { + // main_heap_ptr.sub(1).write(data); + // &*(main_heap_ptr as *const VmCtx) + // } } /// Returns a slice of the contents of allocated linear memory. @@ -582,20 +570,17 @@ impl Clone for Instance { } } -extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 { - // return 0; - unimplemented!(); - // let instance = &vmctx - // .data() - // .user_data - // .instance; +extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &mut VmCtx) -> i32 { + return 0; + // unimplemented!(); + // let instance = &vmctx.user_data.instance; - // let mut memory = &mut instance.memories[memory_index as usize]; + // let mut memory = instance.memories[memory_index as usize]; // if let Some(old_size) = memory.grow(size) { // old_size as i32 // } else { - -1 + // -1 // } // unsafe { @@ -608,18 +593,24 @@ extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &VmCtx) -> i32 { } extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 { + let instance = &vmctx.user_data.instance; + let memory = &instance.memories[memory_index as usize]; + memory.current_size() as u32 + // return 0; - println!("current_memory::init {:?}", memory_index); - let instance = &vmctx.data().user_data.instance; + // unimplemented!(); - let memory = &instance.memories[memory_index as usize]; - println!( - "INSPECTED MEMORY ({:?}) {:?}", - memory.current_size(), - instance.inspect_memory(0, 0, 1) - ); + // println!("current_memory::init {:?}", memory_index); + // let instance = &vmctx.data().user_data.instance; - memory.current_size() as u32 + // let memory = &instance.memories[memory_index as usize]; + // println!( + // "INSPECTED MEMORY ({:?}) {:?}", + // memory.current_size(), + // instance.inspect_memory(0, 0, 1) + // ); + + // memory.current_size() as u32 // return 1; // let vm = unsafe { // (*vmctx) as *mut VmCtx diff --git a/src/webassembly/memory.rs b/src/webassembly/memory.rs index dcc5b816ec6..307ad6d59b3 100644 --- a/src/webassembly/memory.rs +++ b/src/webassembly/memory.rs @@ -36,10 +36,11 @@ impl LinearMemory { initial, maximum ); - let len: u64 = PAGE_SIZE as u64 * match maximum { - Some(val) => val as u64, - None => initial as u64, - }; + let len: u64 = PAGE_SIZE as u64 + * match maximum { + Some(val) => val as u64, + None => initial as u64, + }; let len = if len == 0 { PAGE_SIZE as u64 } else { len }; let mmap = MmapMut::map_anon(len as usize).unwrap(); diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index 54a0c72cbc0..5848e9bacb8 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -407,74 +407,88 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { } fn make_table(&mut self, func: &mut ir::Function, table_index: TableIndex) -> ir::Table { - // OLD - // Create a table whose base address is stored at `vmctx+0`. - // let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); - // let base_gv = func.create_global_value(ir::GlobalValueData::Load { - // base: vmctx, - // offset: Offset32::new(0), - // global_type: self.pointer_type(), - // }); - // let bound_gv = func.create_global_value(ir::GlobalValueData::Load { - // base: vmctx, - // offset: Offset32::new(0), - // global_type: I32, - // }); - - // func.create_table(ir::TableData { - // base_gv, - // min_size: Imm64::new(0), - // bound_gv, - // element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2), - // index_type: I32, - // }) - + let vmctx = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_size = self.ptr_size(); - let base = self.mod_info.tables_base.unwrap_or_else(|| { - let tables_offset = self.ptr_size() as i32 * -1; - let new_base = func.create_global_value(ir::GlobalValueData::VMContext {}); - // { - // offset: tables_offset.into(), - // }); - // self.mod_info.globals_base = Some(new_base); - new_base + // Given a vmctx, we want to retrieve vmctx.tables + // Create a table whose base address is stored at `vmctx+112`. + // 112 is the offset of the vmctx.tables pointer respect to vmctx pointer + let base = func.create_global_value(ir::GlobalValueData::Load { + base: vmctx, + offset: Offset32::new(112), + global_type: self.pointer_type(), }); + // This will be 0 when the index is 0, not sure if the offset will work regardless let table_data_offset = (table_index as usize * ptr_size * 2) as i32; - let new_table_addr_addr = func.create_global_value(ir::GlobalValueData::Load { - base, - offset: table_data_offset.into(), - global_type: self.pointer_type(), // Might be I32 - }); - let new_table_addr = func.create_global_value(ir::GlobalValueData::Load { - base: new_table_addr_addr, - offset: 0.into(), - global_type: self.pointer_type(), // Might be I32 - }); - - let new_table_bounds_addr = func.create_global_value(ir::GlobalValueData::Load { - base, - offset: (table_data_offset + ptr_size as i32).into(), - global_type: self.pointer_type(), // Might be I32 + // We get the pointer for our table index + let base_gv = func.create_global_value(ir::GlobalValueData::Load { + base: base, + offset: Offset32::new(table_data_offset), + global_type: self.pointer_type(), }); - let new_table_bounds = func.create_global_value(ir::GlobalValueData::Load { - base: new_table_bounds_addr, - offset: 0.into(), - global_type: I32, // Might be self.pointer_type() + let bound_gv = func.create_global_value(ir::GlobalValueData::Load { + base: base, + offset: Offset32::new(table_data_offset), + global_type: I64, }); let table = func.create_table(ir::TableData { - base_gv: new_table_addr, + base_gv: base_gv, min_size: Imm64::new(0), - // min_size: (self.mod_info.tables[table_index].size as i64).into(), - bound_gv: new_table_bounds, - element_size: (ptr_size as i64).into(), - index_type: I32, + bound_gv, + element_size: Imm64::new(i64::from(self.pointer_bytes())), + index_type: self.pointer_type(), }); - + // println!("FUNC {:?}", func); table + // let ptr_size = self.ptr_size(); + + // let base = self.mod_info.tables_base.unwrap_or_else(|| { + // let tables_offset = self.ptr_size() as i32 * -1; + // let new_base = func.create_global_value(ir::GlobalValueData::VMContext {}); + // // { + // // offset: tables_offset.into(), + // // }); + // // self.mod_info.globals_base = Some(new_base); + // new_base + // }); + + // let table_data_offset = (table_index as usize * ptr_size * 2) as i32; + + // let new_table_addr_addr = func.create_global_value(ir::GlobalValueData::Load { + // base, + // offset: table_data_offset.into(), + // global_type: self.pointer_type(), // Might be I32 + // }); + // let new_table_addr = func.create_global_value(ir::GlobalValueData::Load { + // base: new_table_addr_addr, + // offset: 0.into(), + // global_type: self.pointer_type(), // Might be I32 + // }); + + // let new_table_bounds_addr = func.create_global_value(ir::GlobalValueData::Load { + // base, + // offset: (table_data_offset + ptr_size as i32).into(), + // global_type: self.pointer_type(), // Might be I32 + // }); + // let new_table_bounds = func.create_global_value(ir::GlobalValueData::Load { + // base: new_table_bounds_addr, + // offset: 0.into(), + // global_type: I32, // Might be self.pointer_type() + // }); + + // let table = func.create_table(ir::TableData { + // base_gv: new_table_addr, + // min_size: Imm64::new(0), + // // min_size: (self.mod_info.tables[table_index].size as i64).into(), + // bound_gv: new_table_bounds, + // element_size: (ptr_size as i64).into(), + // index_type: I32, + // }); + + // table } fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef { @@ -501,7 +515,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { &mut self, mut pos: FuncCursor, _table_index: TableIndex, - _table: ir::Table, + table: ir::Table, _sig_index: SignatureIndex, sig_ref: ir::SigRef, callee: ir::Value, @@ -518,15 +532,20 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // TODO: Generate bounds checking code. let ptr = self.pointer_type(); let callee_offset = if ptr == I32 { - pos.ins().imul_imm(callee, 4) + // pos.ins().imul_imm(callee, 4) + callee } else { let ext = pos.ins().uextend(I64, callee); - pos.ins().imul_imm(ext, 4) + ext + // pos.ins().imul_imm(ext, 4) }; + let entry_addr = pos + .ins() + .table_addr(self.pointer_type(), table, callee_offset, 0); let mut mflags = ir::MemFlags::new(); mflags.set_notrap(); mflags.set_aligned(); - let func_ptr = pos.ins().load(ptr, mflags, callee_offset, 0); + let func_ptr = pos.ins().load(ptr, mflags, entry_addr, 0); // Build a value list for the indirect call instruction containing the callee, call_args, // and the vmctx parameter. @@ -535,10 +554,14 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists); args.push(vmctx, &mut pos.func.dfg.value_lists); - Ok(pos + let inst = pos .ins() .CallIndirect(ir::Opcode::CallIndirect, INVALID, sig_ref, args) - .0) + .0; + + // println!("FUNC {:?}", pos.func); + + Ok(inst) } fn translate_call(