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