call_ref.wast 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. (module
  2. (type $ii (func (param i32) (result i32)))
  3. (func $apply (param $f (ref $ii)) (param $x i32) (result i32)
  4. (call_ref $ii (local.get $x) (local.get $f))
  5. )
  6. (func $f (type $ii) (i32.mul (local.get 0) (local.get 0)))
  7. (func $g (type $ii) (i32.sub (i32.const 0) (local.get 0)))
  8. (elem declare func $f $g)
  9. (func (export "run") (param $x i32) (result i32)
  10. (local $rf (ref null $ii))
  11. (local $rg (ref null $ii))
  12. (local.set $rf (ref.func $f))
  13. (local.set $rg (ref.func $g))
  14. (call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg))
  15. )
  16. (func (export "null") (result i32)
  17. (call_ref $ii (i32.const 1) (ref.null $ii))
  18. )
  19. ;; Recursion
  20. (type $ll (func (param i64) (result i64)))
  21. (type $lll (func (param i64 i64) (result i64)))
  22. (elem declare func $fac)
  23. (global $fac (ref $ll) (ref.func $fac))
  24. (func $fac (export "fac") (type $ll)
  25. (if (result i64) (i64.eqz (local.get 0))
  26. (then (i64.const 1))
  27. (else
  28. (i64.mul
  29. (local.get 0)
  30. (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
  31. )
  32. )
  33. )
  34. )
  35. (elem declare func $fac-acc)
  36. (global $fac-acc (ref $lll) (ref.func $fac-acc))
  37. (func $fac-acc (export "fac-acc") (type $lll)
  38. (if (result i64) (i64.eqz (local.get 0))
  39. (then (local.get 1))
  40. (else
  41. (call_ref $lll
  42. (i64.sub (local.get 0) (i64.const 1))
  43. (i64.mul (local.get 0) (local.get 1))
  44. (global.get $fac-acc)
  45. )
  46. )
  47. )
  48. )
  49. (elem declare func $fib)
  50. (global $fib (ref $ll) (ref.func $fib))
  51. (func $fib (export "fib") (type $ll)
  52. (if (result i64) (i64.le_u (local.get 0) (i64.const 1))
  53. (then (i64.const 1))
  54. (else
  55. (i64.add
  56. (call_ref $ll (i64.sub (local.get 0) (i64.const 2)) (global.get $fib))
  57. (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fib))
  58. )
  59. )
  60. )
  61. )
  62. (elem declare func $even $odd)
  63. (global $even (ref $ll) (ref.func $even))
  64. (global $odd (ref $ll) (ref.func $odd))
  65. (func $even (export "even") (type $ll)
  66. (if (result i64) (i64.eqz (local.get 0))
  67. (then (i64.const 44))
  68. (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $odd)))
  69. )
  70. )
  71. (func $odd (export "odd") (type $ll)
  72. (if (result i64) (i64.eqz (local.get 0))
  73. (then (i64.const 99))
  74. (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
  75. )
  76. )
  77. )
  78. (assert_return (invoke "run" (i32.const 0)) (i32.const 0))
  79. (assert_return (invoke "run" (i32.const 3)) (i32.const -9))
  80. (assert_trap (invoke "null") "null function")
  81. (assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
  82. (assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
  83. (assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
  84. (assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
  85. (assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
  86. (assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
  87. (assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
  88. (assert_return
  89. (invoke "fac-acc" (i64.const 25) (i64.const 1))
  90. (i64.const 7034535277573963776)
  91. )
  92. (assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
  93. (assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
  94. (assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
  95. (assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
  96. (assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
  97. (assert_return (invoke "even" (i64.const 0)) (i64.const 44))
  98. (assert_return (invoke "even" (i64.const 1)) (i64.const 99))
  99. (assert_return (invoke "even" (i64.const 100)) (i64.const 44))
  100. (assert_return (invoke "even" (i64.const 77)) (i64.const 99))
  101. (assert_return (invoke "odd" (i64.const 0)) (i64.const 99))
  102. (assert_return (invoke "odd" (i64.const 1)) (i64.const 44))
  103. (assert_return (invoke "odd" (i64.const 200)) (i64.const 99))
  104. (assert_return (invoke "odd" (i64.const 77)) (i64.const 44))
  105. ;; Unreachable typing.
  106. (module
  107. (type $t (func))
  108. (func (export "unreachable") (result i32)
  109. (unreachable)
  110. (call_ref $t)
  111. )
  112. )
  113. (assert_trap (invoke "unreachable") "unreachable")
  114. (module
  115. (elem declare func $f)
  116. (type $t (func (param i32) (result i32)))
  117. (func $f (param i32) (result i32) (local.get 0))
  118. (func (export "unreachable") (result i32)
  119. (unreachable)
  120. (ref.func $f)
  121. (call_ref $t)
  122. )
  123. )
  124. (assert_trap (invoke "unreachable") "unreachable")
  125. (module
  126. (elem declare func $f)
  127. (type $t (func (param i32) (result i32)))
  128. (func $f (param i32) (result i32) (local.get 0))
  129. (func (export "unreachable") (result i32)
  130. (unreachable)
  131. (i32.const 0)
  132. (ref.func $f)
  133. (call_ref $t)
  134. (drop)
  135. (i32.const 0)
  136. )
  137. )
  138. (assert_trap (invoke "unreachable") "unreachable")
  139. (assert_invalid
  140. (module
  141. (elem declare func $f)
  142. (type $t (func (param i32) (result i32)))
  143. (func $f (param i32) (result i32) (local.get 0))
  144. (func (export "unreachable") (result i32)
  145. (unreachable)
  146. (i64.const 0)
  147. (ref.func $f)
  148. (call_ref $t)
  149. )
  150. )
  151. "type mismatch"
  152. )
  153. (assert_invalid
  154. (module
  155. (elem declare func $f)
  156. (type $t (func (param i32) (result i32)))
  157. (func $f (param i32) (result i32) (local.get 0))
  158. (func (export "unreachable") (result i32)
  159. (unreachable)
  160. (ref.func $f)
  161. (call_ref $t)
  162. (drop)
  163. (i64.const 0)
  164. )
  165. )
  166. "type mismatch"
  167. )
  168. (assert_invalid
  169. (module
  170. (type $t (func))
  171. (func $f (param $r externref)
  172. (call_ref $t (local.get $r))
  173. )
  174. )
  175. "type mismatch"
  176. )