wa-lang.org/wazero@v1.0.2/internal/integration_test/spectest/v1/testdata/call_indirect.wast (about)

     1  ;; Test `call_indirect` operator
     2  
     3  (module
     4    ;; Auxiliary definitions
     5    (type $proc (func))
     6    (type $out-i32 (func (result i32)))
     7    (type $out-i64 (func (result i64)))
     8    (type $out-f32 (func (result f32)))
     9    (type $out-f64 (func (result f64)))
    10    (type $over-i32 (func (param i32) (result i32)))
    11    (type $over-i64 (func (param i64) (result i64)))
    12    (type $over-f32 (func (param f32) (result f32)))
    13    (type $over-f64 (func (param f64) (result f64)))
    14    (type $f32-i32 (func (param f32 i32) (result i32)))
    15    (type $i32-i64 (func (param i32 i64) (result i64)))
    16    (type $f64-f32 (func (param f64 f32) (result f32)))
    17    (type $i64-f64 (func (param i64 f64) (result f64)))
    18    (type $over-i32-duplicate (func (param i32) (result i32)))
    19    (type $over-i64-duplicate (func (param i64) (result i64)))
    20    (type $over-f32-duplicate (func (param f32) (result f32)))
    21    (type $over-f64-duplicate (func (param f64) (result f64)))
    22  
    23    (func $const-i32 (type $out-i32) (i32.const 0x132))
    24    (func $const-i64 (type $out-i64) (i64.const 0x164))
    25    (func $const-f32 (type $out-f32) (f32.const 0xf32))
    26    (func $const-f64 (type $out-f64) (f64.const 0xf64))
    27  
    28    (func $id-i32 (type $over-i32) (local.get 0))
    29    (func $id-i64 (type $over-i64) (local.get 0))
    30    (func $id-f32 (type $over-f32) (local.get 0))
    31    (func $id-f64 (type $over-f64) (local.get 0))
    32  
    33    (func $i32-i64 (type $i32-i64) (local.get 1))
    34    (func $i64-f64 (type $i64-f64) (local.get 1))
    35    (func $f32-i32 (type $f32-i32) (local.get 1))
    36    (func $f64-f32 (type $f64-f32) (local.get 1))
    37  
    38    (func $over-i32-duplicate (type $over-i32-duplicate) (local.get 0))
    39    (func $over-i64-duplicate (type $over-i64-duplicate) (local.get 0))
    40    (func $over-f32-duplicate (type $over-f32-duplicate) (local.get 0))
    41    (func $over-f64-duplicate (type $over-f64-duplicate) (local.get 0))
    42  
    43    (table funcref
    44      (elem
    45        $const-i32 $const-i64 $const-f32 $const-f64
    46        $id-i32 $id-i64 $id-f32 $id-f64
    47        $f32-i32 $i32-i64 $f64-f32 $i64-f64
    48        $fac-i64 $fib-i64 $even $odd
    49        $runaway $mutual-runaway1 $mutual-runaway2
    50        $over-i32-duplicate $over-i64-duplicate
    51        $over-f32-duplicate $over-f64-duplicate
    52        $fac-i32 $fac-f32 $fac-f64
    53        $fib-i32 $fib-f32 $fib-f64
    54      )
    55    )
    56  
    57    ;; Syntax
    58  
    59    (func
    60      (call_indirect (i32.const 0))
    61      (call_indirect (param i64) (i64.const 0) (i32.const 0))
    62      (call_indirect (param i64) (param) (param f64 i32 i64)
    63        (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0)
    64      )
    65      (call_indirect (result) (i32.const 0))
    66      (drop (i32.eqz (call_indirect (result i32) (i32.const 0))))
    67      (drop (i32.eqz (call_indirect (result i32) (result) (i32.const 0))))
    68      (drop (i32.eqz
    69        (call_indirect (param i64) (result i32) (i64.const 0) (i32.const 0))
    70      ))
    71      (drop (i32.eqz
    72        (call_indirect
    73          (param) (param i64) (param) (param f64 i32 i64) (param) (param)
    74          (result) (result i32) (result) (result)
    75          (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0)
    76        )
    77      ))
    78      (drop (i64.eqz
    79        (call_indirect (type $over-i64) (param i64) (result i64)
    80          (i64.const 0) (i32.const 0)
    81        )
    82      ))
    83    )
    84  
    85    ;; Typing
    86  
    87    (func (export "type-i32") (result i32)
    88      (call_indirect (type $out-i32) (i32.const 0))
    89    )
    90    (func (export "type-i64") (result i64)
    91      (call_indirect (type $out-i64) (i32.const 1))
    92    )
    93    (func (export "type-f32") (result f32)
    94      (call_indirect (type $out-f32) (i32.const 2))
    95    )
    96    (func (export "type-f64") (result f64)
    97      (call_indirect (type $out-f64) (i32.const 3))
    98    )
    99  
   100    (func (export "type-index") (result i64)
   101      (call_indirect (type $over-i64) (i64.const 100) (i32.const 5))
   102    )
   103  
   104    (func (export "type-first-i32") (result i32)
   105      (call_indirect (type $over-i32) (i32.const 32) (i32.const 4))
   106    )
   107    (func (export "type-first-i64") (result i64)
   108      (call_indirect (type $over-i64) (i64.const 64) (i32.const 5))
   109    )
   110    (func (export "type-first-f32") (result f32)
   111      (call_indirect (type $over-f32) (f32.const 1.32) (i32.const 6))
   112    )
   113    (func (export "type-first-f64") (result f64)
   114      (call_indirect (type $over-f64) (f64.const 1.64) (i32.const 7))
   115    )
   116  
   117    (func (export "type-second-i32") (result i32)
   118      (call_indirect (type $f32-i32) (f32.const 32.1) (i32.const 32) (i32.const 8))
   119    )
   120    (func (export "type-second-i64") (result i64)
   121      (call_indirect (type $i32-i64) (i32.const 32) (i64.const 64) (i32.const 9))
   122    )
   123    (func (export "type-second-f32") (result f32)
   124      (call_indirect (type $f64-f32) (f64.const 64) (f32.const 32) (i32.const 10))
   125    )
   126    (func (export "type-second-f64") (result f64)
   127      (call_indirect (type $i64-f64) (i64.const 64) (f64.const 64.1) (i32.const 11))
   128    )
   129  
   130    ;; Dispatch
   131  
   132    (func (export "dispatch") (param i32 i64) (result i64)
   133      (call_indirect (type $over-i64) (local.get 1) (local.get 0))
   134    )
   135  
   136    (func (export "dispatch-structural-i64") (param i32) (result i64)
   137      (call_indirect (type $over-i64-duplicate) (i64.const 9) (local.get 0))
   138    )
   139    (func (export "dispatch-structural-i32") (param i32) (result i32)
   140      (call_indirect (type $over-i32-duplicate) (i32.const 9) (local.get 0))
   141    )
   142    (func (export "dispatch-structural-f32") (param i32) (result f32)
   143      (call_indirect (type $over-f32-duplicate) (f32.const 9.0) (local.get 0))
   144    )
   145    (func (export "dispatch-structural-f64") (param i32) (result f64)
   146      (call_indirect (type $over-f64-duplicate) (f64.const 9.0) (local.get 0))
   147    )
   148  
   149    ;; Recursion
   150  
   151    (func $fac-i64 (export "fac-i64") (type $over-i64)
   152      (if (result i64) (i64.eqz (local.get 0))
   153        (then (i64.const 1))
   154        (else
   155          (i64.mul
   156            (local.get 0)
   157            (call_indirect (type $over-i64)
   158              (i64.sub (local.get 0) (i64.const 1))
   159              (i32.const 12)
   160            )
   161          )
   162        )
   163      )
   164    )
   165  
   166    (func $fib-i64 (export "fib-i64") (type $over-i64)
   167      (if (result i64) (i64.le_u (local.get 0) (i64.const 1))
   168        (then (i64.const 1))
   169        (else
   170          (i64.add
   171            (call_indirect (type $over-i64)
   172              (i64.sub (local.get 0) (i64.const 2))
   173              (i32.const 13)
   174            )
   175            (call_indirect (type $over-i64)
   176              (i64.sub (local.get 0) (i64.const 1))
   177              (i32.const 13)
   178            )
   179          )
   180        )
   181      )
   182    )
   183  
   184    (func $fac-i32 (export "fac-i32") (type $over-i32)
   185      (if (result i32) (i32.eqz (local.get 0))
   186        (then (i32.const 1))
   187        (else
   188          (i32.mul
   189            (local.get 0)
   190            (call_indirect (type $over-i32)
   191              (i32.sub (local.get 0) (i32.const 1))
   192              (i32.const 23)
   193            )
   194          )
   195        )
   196      )
   197    )
   198  
   199    (func $fac-f32 (export "fac-f32") (type $over-f32)
   200      (if (result f32) (f32.eq (local.get 0) (f32.const 0.0))
   201        (then (f32.const 1.0))
   202        (else
   203          (f32.mul
   204            (local.get 0)
   205            (call_indirect (type $over-f32)
   206              (f32.sub (local.get 0) (f32.const 1.0))
   207              (i32.const 24)
   208            )
   209          )
   210        )
   211      )
   212    )
   213  
   214    (func $fac-f64 (export "fac-f64") (type $over-f64)
   215      (if (result f64) (f64.eq (local.get 0) (f64.const 0.0))
   216        (then (f64.const 1.0))
   217        (else
   218          (f64.mul
   219            (local.get 0)
   220            (call_indirect (type $over-f64)
   221              (f64.sub (local.get 0) (f64.const 1.0))
   222              (i32.const 25)
   223            )
   224          )
   225        )
   226      )
   227    )
   228  
   229    (func $fib-i32 (export "fib-i32") (type $over-i32)
   230      (if (result i32) (i32.le_u (local.get 0) (i32.const 1))
   231        (then (i32.const 1))
   232        (else
   233          (i32.add
   234            (call_indirect (type $over-i32)
   235              (i32.sub (local.get 0) (i32.const 2))
   236              (i32.const 26)
   237            )
   238            (call_indirect (type $over-i32)
   239              (i32.sub (local.get 0) (i32.const 1))
   240              (i32.const 26)
   241            )
   242          )
   243        )
   244      )
   245    )
   246  
   247    (func $fib-f32 (export "fib-f32") (type $over-f32)
   248      (if (result f32) (f32.le (local.get 0) (f32.const 1.0))
   249        (then (f32.const 1.0))
   250        (else
   251          (f32.add
   252            (call_indirect (type $over-f32)
   253              (f32.sub (local.get 0) (f32.const 2.0))
   254              (i32.const 27)
   255            )
   256            (call_indirect (type $over-f32)
   257              (f32.sub (local.get 0) (f32.const 1.0))
   258              (i32.const 27)
   259            )
   260          )
   261        )
   262      )
   263    )
   264  
   265    (func $fib-f64 (export "fib-f64") (type $over-f64)
   266      (if (result f64) (f64.le (local.get 0) (f64.const 1.0))
   267        (then (f64.const 1.0))
   268        (else
   269          (f64.add
   270            (call_indirect (type $over-f64)
   271              (f64.sub (local.get 0) (f64.const 2.0))
   272              (i32.const 28)
   273            )
   274            (call_indirect (type $over-f64)
   275              (f64.sub (local.get 0) (f64.const 1.0))
   276              (i32.const 28)
   277            )
   278          )
   279        )
   280      )
   281    )
   282  
   283    (func $even (export "even") (param i32) (result i32)
   284      (if (result i32) (i32.eqz (local.get 0))
   285        (then (i32.const 44))
   286        (else
   287          (call_indirect (type $over-i32)
   288            (i32.sub (local.get 0) (i32.const 1))
   289            (i32.const 15)
   290          )
   291        )
   292      )
   293    )
   294    (func $odd (export "odd") (param i32) (result i32)
   295      (if (result i32) (i32.eqz (local.get 0))
   296        (then (i32.const 99))
   297        (else
   298          (call_indirect (type $over-i32)
   299            (i32.sub (local.get 0) (i32.const 1))
   300            (i32.const 14)
   301          )
   302        )
   303      )
   304    )
   305  
   306    ;; Stack exhaustion
   307  
   308    ;; Implementations are required to have every call consume some abstract
   309    ;; resource towards exhausting some abstract finite limit, such that
   310    ;; infinitely recursive test cases reliably trap in finite time. This is
   311    ;; because otherwise applications could come to depend on it on those
   312    ;; implementations and be incompatible with implementations that don't do
   313    ;; it (or don't do it under the same circumstances).
   314  
   315    (func $runaway (export "runaway") (call_indirect (type $proc) (i32.const 16)))
   316  
   317    (func $mutual-runaway1 (export "mutual-runaway") (call_indirect (type $proc) (i32.const 18)))
   318    (func $mutual-runaway2 (call_indirect (type $proc) (i32.const 17)))
   319  
   320    ;; As parameter of control constructs and instructions
   321  
   322    (memory 1)
   323  
   324    (func (export "as-select-first") (result i32)
   325      (select (call_indirect (type $out-i32) (i32.const 0)) (i32.const 2) (i32.const 3))
   326    )
   327    (func (export "as-select-mid") (result i32)
   328      (select (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (i32.const 3))
   329    )
   330    (func (export "as-select-last") (result i32)
   331      (select (i32.const 2) (i32.const 3) (call_indirect (type $out-i32) (i32.const 0)))
   332    )
   333  
   334    (func (export "as-if-condition") (result i32)
   335      (if (result i32) (call_indirect (type $out-i32) (i32.const 0)) (then (i32.const 1)) (else (i32.const 2)))
   336    )
   337  
   338    (func (export "as-br_if-first") (result i64)
   339      (block (result i64) (br_if 0 (call_indirect (type $out-i64) (i32.const 1)) (i32.const 2)))
   340    )
   341    (func (export "as-br_if-last") (result i32)
   342      (block (result i32) (br_if 0 (i32.const 2) (call_indirect (type $out-i32) (i32.const 0))))
   343    )
   344  
   345    (func (export "as-br_table-first") (result f32)
   346      (block (result f32) (call_indirect (type $out-f32) (i32.const 2)) (i32.const 2) (br_table 0 0))
   347    )
   348    (func (export "as-br_table-last") (result i32)
   349      (block (result i32) (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (br_table 0 0))
   350    )
   351  
   352    (func (export "as-store-first")
   353      (call_indirect (type $out-i32) (i32.const 0)) (i32.const 1) (i32.store)
   354    )
   355    (func (export "as-store-last")
   356      (i32.const 10) (call_indirect (type $out-f64) (i32.const 3)) (f64.store)
   357    )
   358  
   359    (func (export "as-memory.grow-value") (result i32)
   360      (memory.grow (call_indirect (type $out-i32) (i32.const 0)))
   361    )
   362    (func (export "as-return-value") (result i32)
   363      (call_indirect (type $over-i32) (i32.const 1) (i32.const 4)) (return)
   364    )
   365    (func (export "as-drop-operand")
   366      (call_indirect (type $over-i64) (i64.const 1) (i32.const 5)) (drop)
   367    )
   368    (func (export "as-br-value") (result f32)
   369      (block (result f32) (br 0 (call_indirect (type $over-f32) (f32.const 1) (i32.const 6))))
   370    )
   371    (func (export "as-local.set-value") (result f64)
   372      (local f64) (local.set 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7))) (local.get 0)
   373    )
   374    (func (export "as-local.tee-value") (result f64)
   375      (local f64) (local.tee 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7)))
   376    )
   377    (global $a (mut f64) (f64.const 10.0))
   378    (func (export "as-global.set-value") (result f64)
   379      (global.set $a (call_indirect (type $over-f64) (f64.const 1.0) (i32.const 7)))
   380      (global.get $a)
   381    )
   382  
   383    (func (export "as-load-operand") (result i32)
   384      (i32.load (call_indirect (type $out-i32) (i32.const 0)))
   385    )
   386  
   387    (func (export "as-unary-operand") (result f32)
   388      (block (result f32)
   389        (f32.sqrt
   390          (call_indirect (type $over-f32) (f32.const 0x0p+0) (i32.const 6))
   391        )
   392      )
   393    )
   394  
   395    (func (export "as-binary-left") (result i32)
   396      (block (result i32)
   397        (i32.add
   398          (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
   399          (i32.const 10)
   400        )
   401      )
   402    )
   403    (func (export "as-binary-right") (result i32)
   404      (block (result i32)
   405        (i32.sub
   406          (i32.const 10)
   407          (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
   408        )
   409      )
   410    )
   411  
   412    (func (export "as-test-operand") (result i32)
   413      (block (result i32)
   414        (i32.eqz
   415          (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
   416        )
   417      )
   418    )
   419  
   420    (func (export "as-compare-left") (result i32)
   421      (block (result i32)
   422        (i32.le_u
   423          (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
   424          (i32.const 10)
   425        )
   426      )
   427    )
   428    (func (export "as-compare-right") (result i32)
   429      (block (result i32)
   430        (i32.ne
   431          (i32.const 10)
   432          (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
   433        )
   434      )
   435    )
   436  
   437    (func (export "as-convert-operand") (result i64)
   438      (block (result i64)
   439        (i64.extend_i32_s
   440          (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
   441        )
   442      )
   443    )
   444  
   445  )
   446  
   447  (assert_return (invoke "type-i32") (i32.const 0x132))
   448  (assert_return (invoke "type-i64") (i64.const 0x164))
   449  (assert_return (invoke "type-f32") (f32.const 0xf32))
   450  (assert_return (invoke "type-f64") (f64.const 0xf64))
   451  
   452  (assert_return (invoke "type-index") (i64.const 100))
   453  
   454  (assert_return (invoke "type-first-i32") (i32.const 32))
   455  (assert_return (invoke "type-first-i64") (i64.const 64))
   456  (assert_return (invoke "type-first-f32") (f32.const 1.32))
   457  (assert_return (invoke "type-first-f64") (f64.const 1.64))
   458  
   459  (assert_return (invoke "type-second-i32") (i32.const 32))
   460  (assert_return (invoke "type-second-i64") (i64.const 64))
   461  (assert_return (invoke "type-second-f32") (f32.const 32))
   462  (assert_return (invoke "type-second-f64") (f64.const 64.1))
   463  
   464  (assert_return (invoke "dispatch" (i32.const 5) (i64.const 2)) (i64.const 2))
   465  (assert_return (invoke "dispatch" (i32.const 5) (i64.const 5)) (i64.const 5))
   466  (assert_return (invoke "dispatch" (i32.const 12) (i64.const 5)) (i64.const 120))
   467  (assert_return (invoke "dispatch" (i32.const 13) (i64.const 5)) (i64.const 8))
   468  (assert_return (invoke "dispatch" (i32.const 20) (i64.const 2)) (i64.const 2))
   469  (assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call type mismatch")
   470  (assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call type mismatch")
   471  (assert_trap (invoke "dispatch" (i32.const 29) (i64.const 2)) "undefined element")
   472  (assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element")
   473  (assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element")
   474  
   475  (assert_return (invoke "dispatch-structural-i64" (i32.const 5)) (i64.const 9))
   476  (assert_return (invoke "dispatch-structural-i64" (i32.const 12)) (i64.const 362880))
   477  (assert_return (invoke "dispatch-structural-i64" (i32.const 13)) (i64.const 55))
   478  (assert_return (invoke "dispatch-structural-i64" (i32.const 20)) (i64.const 9))
   479  (assert_trap (invoke "dispatch-structural-i64" (i32.const 11)) "indirect call type mismatch")
   480  (assert_trap (invoke "dispatch-structural-i64" (i32.const 22)) "indirect call type mismatch")
   481  
   482  (assert_return (invoke "dispatch-structural-i32" (i32.const 4)) (i32.const 9))
   483  (assert_return (invoke "dispatch-structural-i32" (i32.const 23)) (i32.const 362880))
   484  (assert_return (invoke "dispatch-structural-i32" (i32.const 26)) (i32.const 55))
   485  (assert_return (invoke "dispatch-structural-i32" (i32.const 19)) (i32.const 9))
   486  (assert_trap (invoke "dispatch-structural-i32" (i32.const 9)) "indirect call type mismatch")
   487  (assert_trap (invoke "dispatch-structural-i32" (i32.const 21)) "indirect call type mismatch")
   488  
   489  (assert_return (invoke "dispatch-structural-f32" (i32.const 6)) (f32.const 9.0))
   490  (assert_return (invoke "dispatch-structural-f32" (i32.const 24)) (f32.const 362880.0))
   491  (assert_return (invoke "dispatch-structural-f32" (i32.const 27)) (f32.const 55.0))
   492  (assert_return (invoke "dispatch-structural-f32" (i32.const 21)) (f32.const 9.0))
   493  (assert_trap (invoke "dispatch-structural-f32" (i32.const 8)) "indirect call type mismatch")
   494  (assert_trap (invoke "dispatch-structural-f32" (i32.const 19)) "indirect call type mismatch")
   495  
   496  (assert_return (invoke "dispatch-structural-f64" (i32.const 7)) (f64.const 9.0))
   497  (assert_return (invoke "dispatch-structural-f64" (i32.const 25)) (f64.const 362880.0))
   498  (assert_return (invoke "dispatch-structural-f64" (i32.const 28)) (f64.const 55.0))
   499  (assert_return (invoke "dispatch-structural-f64" (i32.const 22)) (f64.const 9.0))
   500  (assert_trap (invoke "dispatch-structural-f64" (i32.const 10)) "indirect call type mismatch")
   501  (assert_trap (invoke "dispatch-structural-f64" (i32.const 18)) "indirect call type mismatch")
   502  
   503  (assert_return (invoke "fac-i64" (i64.const 0)) (i64.const 1))
   504  (assert_return (invoke "fac-i64" (i64.const 1)) (i64.const 1))
   505  (assert_return (invoke "fac-i64" (i64.const 5)) (i64.const 120))
   506  (assert_return (invoke "fac-i64" (i64.const 25)) (i64.const 7034535277573963776))
   507  
   508  (assert_return (invoke "fac-i32" (i32.const 0)) (i32.const 1))
   509  (assert_return (invoke "fac-i32" (i32.const 1)) (i32.const 1))
   510  (assert_return (invoke "fac-i32" (i32.const 5)) (i32.const 120))
   511  (assert_return (invoke "fac-i32" (i32.const 10)) (i32.const 3628800))
   512  
   513  (assert_return (invoke "fac-f32" (f32.const 0.0)) (f32.const 1.0))
   514  (assert_return (invoke "fac-f32" (f32.const 1.0)) (f32.const 1.0))
   515  (assert_return (invoke "fac-f32" (f32.const 5.0)) (f32.const 120.0))
   516  (assert_return (invoke "fac-f32" (f32.const 10.0)) (f32.const 3628800.0))
   517  
   518  (assert_return (invoke "fac-f64" (f64.const 0.0)) (f64.const 1.0))
   519  (assert_return (invoke "fac-f64" (f64.const 1.0)) (f64.const 1.0))
   520  (assert_return (invoke "fac-f64" (f64.const 5.0)) (f64.const 120.0))
   521  (assert_return (invoke "fac-f64" (f64.const 10.0)) (f64.const 3628800.0))
   522  
   523  (assert_return (invoke "fib-i64" (i64.const 0)) (i64.const 1))
   524  (assert_return (invoke "fib-i64" (i64.const 1)) (i64.const 1))
   525  (assert_return (invoke "fib-i64" (i64.const 2)) (i64.const 2))
   526  (assert_return (invoke "fib-i64" (i64.const 5)) (i64.const 8))
   527  (assert_return (invoke "fib-i64" (i64.const 20)) (i64.const 10946))
   528  
   529  (assert_return (invoke "fib-i32" (i32.const 0)) (i32.const 1))
   530  (assert_return (invoke "fib-i32" (i32.const 1)) (i32.const 1))
   531  (assert_return (invoke "fib-i32" (i32.const 2)) (i32.const 2))
   532  (assert_return (invoke "fib-i32" (i32.const 5)) (i32.const 8))
   533  (assert_return (invoke "fib-i32" (i32.const 20)) (i32.const 10946))
   534  
   535  (assert_return (invoke "fib-f32" (f32.const 0.0)) (f32.const 1.0))
   536  (assert_return (invoke "fib-f32" (f32.const 1.0)) (f32.const 1.0))
   537  (assert_return (invoke "fib-f32" (f32.const 2.0)) (f32.const 2.0))
   538  (assert_return (invoke "fib-f32" (f32.const 5.0)) (f32.const 8.0))
   539  (assert_return (invoke "fib-f32" (f32.const 20.0)) (f32.const 10946.0))
   540  
   541  (assert_return (invoke "fib-f64" (f64.const 0.0)) (f64.const 1.0))
   542  (assert_return (invoke "fib-f64" (f64.const 1.0)) (f64.const 1.0))
   543  (assert_return (invoke "fib-f64" (f64.const 2.0)) (f64.const 2.0))
   544  (assert_return (invoke "fib-f64" (f64.const 5.0)) (f64.const 8.0))
   545  (assert_return (invoke "fib-f64" (f64.const 20.0)) (f64.const 10946.0))
   546  
   547  (assert_return (invoke "even" (i32.const 0)) (i32.const 44))
   548  (assert_return (invoke "even" (i32.const 1)) (i32.const 99))
   549  (assert_return (invoke "even" (i32.const 100)) (i32.const 44))
   550  (assert_return (invoke "even" (i32.const 77)) (i32.const 99))
   551  (assert_return (invoke "odd" (i32.const 0)) (i32.const 99))
   552  (assert_return (invoke "odd" (i32.const 1)) (i32.const 44))
   553  (assert_return (invoke "odd" (i32.const 200)) (i32.const 99))
   554  (assert_return (invoke "odd" (i32.const 77)) (i32.const 44))
   555  
   556  (assert_exhaustion (invoke "runaway") "call stack exhausted")
   557  (assert_exhaustion (invoke "mutual-runaway") "call stack exhausted")
   558  
   559  (assert_return (invoke "as-select-first") (i32.const 0x132))
   560  (assert_return (invoke "as-select-mid") (i32.const 2))
   561  (assert_return (invoke "as-select-last") (i32.const 2))
   562  
   563  (assert_return (invoke "as-if-condition") (i32.const 1))
   564  
   565  (assert_return (invoke "as-br_if-first") (i64.const 0x164))
   566  (assert_return (invoke "as-br_if-last") (i32.const 2))
   567  
   568  (assert_return (invoke "as-br_table-first") (f32.const 0xf32))
   569  (assert_return (invoke "as-br_table-last") (i32.const 2))
   570  
   571  (assert_return (invoke "as-store-first"))
   572  (assert_return (invoke "as-store-last"))
   573  
   574  (assert_return (invoke "as-memory.grow-value") (i32.const 1))
   575  (assert_return (invoke "as-return-value") (i32.const 1))
   576  (assert_return (invoke "as-drop-operand"))
   577  (assert_return (invoke "as-br-value") (f32.const 1))
   578  (assert_return (invoke "as-local.set-value") (f64.const 1))
   579  (assert_return (invoke "as-local.tee-value") (f64.const 1))
   580  (assert_return (invoke "as-global.set-value") (f64.const 1.0))
   581  (assert_return (invoke "as-load-operand") (i32.const 1))
   582  
   583  (assert_return (invoke "as-unary-operand") (f32.const 0x0p+0))
   584  (assert_return (invoke "as-binary-left") (i32.const 11))
   585  (assert_return (invoke "as-binary-right") (i32.const 9))
   586  (assert_return (invoke "as-test-operand") (i32.const 0))
   587  (assert_return (invoke "as-compare-left") (i32.const 1))
   588  (assert_return (invoke "as-compare-right") (i32.const 1))
   589  (assert_return (invoke "as-convert-operand") (i64.const 1))
   590  
   591  ;; Invalid syntax
   592  
   593  (assert_malformed
   594    (module quote
   595      "(type $sig (func (param i32) (result i32)))"
   596      "(table 0 funcref)"
   597      "(func (result i32)"
   598      "  (call_indirect (type $sig) (result i32) (param i32)"
   599      "    (i32.const 0) (i32.const 0)"
   600      "  )"
   601      ")"
   602    )
   603    "unexpected token"
   604  )
   605  (assert_malformed
   606    (module quote
   607      "(type $sig (func (param i32) (result i32)))"
   608      "(table 0 funcref)"
   609      "(func (result i32)"
   610      "  (call_indirect (param i32) (type $sig) (result i32)"
   611      "    (i32.const 0) (i32.const 0)"
   612      "  )"
   613      ")"
   614    )
   615    "unexpected token"
   616  )
   617  (assert_malformed
   618    (module quote
   619      "(type $sig (func (param i32) (result i32)))"
   620      "(table 0 funcref)"
   621      "(func (result i32)"
   622      "  (call_indirect (param i32) (result i32) (type $sig)"
   623      "    (i32.const 0) (i32.const 0)"
   624      "  )"
   625      ")"
   626    )
   627    "unexpected token"
   628  )
   629  (assert_malformed
   630    (module quote
   631      "(type $sig (func (param i32) (result i32)))"
   632      "(table 0 funcref)"
   633      "(func (result i32)"
   634      "  (call_indirect (result i32) (type $sig) (param i32)"
   635      "    (i32.const 0) (i32.const 0)"
   636      "  )"
   637      ")"
   638    )
   639    "unexpected token"
   640  )
   641  (assert_malformed
   642    (module quote
   643      "(type $sig (func (param i32) (result i32)))"
   644      "(table 0 funcref)"
   645      "(func (result i32)"
   646      "  (call_indirect (result i32) (param i32) (type $sig)"
   647      "    (i32.const 0) (i32.const 0)"
   648      "  )"
   649      ")"
   650    )
   651    "unexpected token"
   652  )
   653  (assert_malformed
   654    (module quote
   655      "(table 0 funcref)"
   656      "(func (result i32)"
   657      "  (call_indirect (result i32) (param i32) (i32.const 0) (i32.const 0))"
   658      ")"
   659    )
   660    "unexpected token"
   661  )
   662  
   663  (assert_malformed
   664    (module quote
   665      "(table 0 funcref)"
   666      "(func (call_indirect (param $x i32) (i32.const 0) (i32.const 0)))"
   667    )
   668    "unexpected token"
   669  )
   670  (assert_malformed
   671    (module quote
   672      "(type $sig (func))"
   673      "(table 0 funcref)"
   674      "(func (result i32)"
   675      "  (call_indirect (type $sig) (result i32) (i32.const 0))"
   676      ")"
   677    )
   678    "inline function type"
   679  )
   680  (assert_malformed
   681    (module quote
   682      "(type $sig (func (param i32) (result i32)))"
   683      "(table 0 funcref)"
   684      "(func (result i32)"
   685      "  (call_indirect (type $sig) (result i32) (i32.const 0))"
   686      ")"
   687    )
   688    "inline function type"
   689  )
   690  (assert_malformed
   691    (module quote
   692      "(type $sig (func (param i32) (result i32)))"
   693      "(table 0 funcref)"
   694      "(func"
   695      "  (call_indirect (type $sig) (param i32) (i32.const 0) (i32.const 0))"
   696      ")"
   697    )
   698    "inline function type"
   699  )
   700  (assert_malformed
   701    (module quote
   702      "(type $sig (func (param i32 i32) (result i32)))"
   703      "(table 0 funcref)"
   704      "(func (result i32)"
   705      "  (call_indirect (type $sig) (param i32) (result i32)"
   706      "    (i32.const 0) (i32.const 0)"
   707      "  )"
   708      ")"
   709    )
   710    "inline function type"
   711  )
   712  
   713  ;; Invalid typing
   714  
   715  (assert_invalid
   716    (module
   717      (type (func))
   718      (func $no-table (call_indirect (type 0) (i32.const 0)))
   719    )
   720    "unknown table"
   721  )
   722  
   723  (assert_invalid
   724    (module
   725      (type (func))
   726      (table 0 funcref)
   727      (func $type-void-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0))))
   728    )
   729    "type mismatch"
   730  )
   731  (assert_invalid
   732    (module
   733      (type (func (result i64)))
   734      (table 0 funcref)
   735      (func $type-num-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0))))
   736    )
   737    "type mismatch"
   738  )
   739  
   740  (assert_invalid
   741    (module
   742      (type (func (param i32)))
   743      (table 0 funcref)
   744      (func $arity-0-vs-1 (call_indirect (type 0) (i32.const 0)))
   745    )
   746    "type mismatch"
   747  )
   748  (assert_invalid
   749    (module
   750      (type (func (param f64 i32)))
   751      (table 0 funcref)
   752      (func $arity-0-vs-2 (call_indirect (type 0) (i32.const 0)))
   753    )
   754    "type mismatch"
   755  )
   756  (assert_invalid
   757    (module
   758      (type (func))
   759      (table 0 funcref)
   760      (func $arity-1-vs-0 (call_indirect (type 0) (i32.const 1) (i32.const 0)))
   761    )
   762    "type mismatch"
   763  )
   764  (assert_invalid
   765    (module
   766      (type (func))
   767      (table 0 funcref)
   768      (func $arity-2-vs-0
   769        (call_indirect (type 0) (f64.const 2) (i32.const 1) (i32.const 0))
   770      )
   771    )
   772    "type mismatch"
   773  )
   774  
   775  (assert_invalid
   776    (module
   777      (type (func (param i32)))
   778      (table 0 funcref)
   779      (func $type-func-void-vs-i32 (call_indirect (type 0) (i32.const 1) (nop)))
   780    )
   781    "type mismatch"
   782  )
   783  (assert_invalid
   784    (module
   785      (type (func (param i32)))
   786      (table 0 funcref)
   787      (func $type-func-num-vs-i32 (call_indirect (type 0) (i32.const 0) (i64.const 1)))
   788    )
   789    "type mismatch"
   790  )
   791  
   792  (assert_invalid
   793    (module
   794      (type (func (param i32 i32)))
   795      (table 0 funcref)
   796      (func $type-first-void-vs-num
   797        (call_indirect (type 0) (nop) (i32.const 1) (i32.const 0))
   798      )
   799    )
   800    "type mismatch"
   801  )
   802  (assert_invalid
   803    (module
   804      (type (func (param i32 i32)))
   805      (table 0 funcref)
   806      (func $type-second-void-vs-num
   807        (call_indirect (type 0) (i32.const 1) (nop) (i32.const 0))
   808      )
   809    )
   810    "type mismatch"
   811  )
   812  (assert_invalid
   813    (module
   814      (type (func (param i32 f64)))
   815      (table 0 funcref)
   816      (func $type-first-num-vs-num
   817        (call_indirect (type 0) (f64.const 1) (i32.const 1) (i32.const 0))
   818      )
   819    )
   820    "type mismatch"
   821  )
   822  (assert_invalid
   823    (module
   824      (type (func (param f64 i32)))
   825      (table 0 funcref)
   826      (func $type-second-num-vs-num
   827        (call_indirect (type 0) (i32.const 1) (f64.const 1) (i32.const 0))
   828      )
   829    )
   830    "type mismatch"
   831  )
   832  
   833  (assert_invalid
   834    (module
   835      (func $f (param i32))
   836      (type $sig (func (param i32)))
   837      (table funcref (elem $f))
   838      (func $type-first-empty-in-block
   839        (block
   840          (call_indirect (type $sig) (i32.const 0))
   841        )
   842      )
   843    )
   844    "type mismatch"
   845  )
   846  (assert_invalid
   847    (module
   848      (func $f (param i32 i32))
   849      (type $sig (func (param i32 i32)))
   850      (table funcref (elem $f))
   851      (func $type-second-empty-in-block
   852        (block
   853          (call_indirect (type $sig) (i32.const 0) (i32.const 0))
   854        )
   855      )
   856    )
   857    "type mismatch"
   858  )
   859  (assert_invalid
   860    (module
   861      (func $f (param i32))
   862      (type $sig (func (param i32)))
   863      (table funcref (elem $f))
   864      (func $type-first-empty-in-loop
   865        (loop
   866          (call_indirect (type $sig) (i32.const 0))
   867        )
   868      )
   869    )
   870    "type mismatch"
   871  )
   872  (assert_invalid
   873    (module
   874      (func $f (param i32 i32))
   875      (type $sig (func (param i32 i32)))
   876      (table funcref (elem $f))
   877      (func $type-second-empty-in-loop
   878        (loop
   879          (call_indirect (type $sig) (i32.const 0) (i32.const 0))
   880        )
   881      )
   882    )
   883    "type mismatch"
   884  )
   885  (assert_invalid
   886    (module
   887      (func $f (param i32))
   888      (type $sig (func (param i32)))
   889      (table funcref (elem $f))
   890      (func $type-first-empty-in-then
   891        (i32.const 0) (i32.const 0)
   892        (if
   893          (then
   894            (call_indirect (type $sig) (i32.const 0))
   895          )
   896        )
   897      )
   898    )
   899    "type mismatch"
   900  )
   901  (assert_invalid
   902    (module
   903      (func $f (param i32 i32))
   904      (type $sig (func (param i32 i32)))
   905      (table funcref (elem $f))
   906      (func $type-second-empty-in-then
   907        (i32.const 0) (i32.const 0)
   908        (if
   909          (then
   910            (call_indirect (type $sig) (i32.const 0) (i32.const 0))
   911          )
   912        )
   913      )
   914    )
   915    "type mismatch"
   916  )
   917  
   918  
   919  ;; Unbound type
   920  
   921  (assert_invalid
   922    (module
   923      (table 0 funcref)
   924      (func $unbound-type (call_indirect (type 1) (i32.const 0)))
   925    )
   926    "unknown type"
   927  )
   928  (assert_invalid
   929    (module
   930      (table 0 funcref)
   931      (func $large-type (call_indirect (type 1012321300) (i32.const 0)))
   932    )
   933    "unknown type"
   934  )
   935  
   936  
   937  ;; Unbound function in table
   938  
   939  (assert_invalid
   940    (module (table funcref (elem 0 0)))
   941    "unknown function 0"
   942  )