reflect.wat 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. ;; The reflect module has four purposes:
  2. ;;
  3. ;; 1. Let embedders (e.g. JS) to know what the type of an object is
  4. ;;
  5. ;; 2. Let embedders access an object's value (e.g. a flonum's value)
  6. ;;
  7. ;; 3. Let embedders construct "value-like" objects: fixnums, bignums,
  8. ;; flonums, compnums, fractions, immutable strings, symbols,
  9. ;; immutable pairs, keywords. Possibly immutable bytevectors and
  10. ;; bitvectors also.
  11. ;;
  12. ;; 4. Let embedders call exported functions and receive their return
  13. ;; values.
  14. ;;
  15. ;; To do this, this module needs some shared state from the Scheme
  16. ;; system: storage locations used for passing parameters and return
  17. ;; values, the continuation stack (to allow for calling), and
  18. ;; string->symbol and string->keyword procedures needed to construct
  19. ;; symbols and keywords.
  20. (module
  21. (func $abort (type $kvarargs) (unreachable))
  22. ;; These grow functions try to grow their corresponding tables,
  23. ;; filling in a sensible default value so as to not require the
  24. ;; tables to be nullable, and abort if that fails.
  25. (func $grow-argv (param $nargs i32)
  26. (br_if 0 (i32.le_s (i32.const 0)
  27. (table.grow
  28. $argv
  29. (ref.i31 (i32.const 0))
  30. (i32.sub (i32.sub (local.get $nargs) (i32.const 8))
  31. (table.size $argv)))))
  32. (unreachable))
  33. (func $grow-ret-stack (param $diff i32)
  34. (br_if 0 (i32.le_s (i32.const 0)
  35. (table.grow $ret-stack (ref.func $abort)
  36. (local.get $diff))))
  37. (unreachable))
  38. (func $describe (export "describe") (param $scm (ref eq)) (result (ref string))
  39. (local $tmp i32)
  40. (block $Ldone (result (ref string))
  41. ;; Verrrrry annoyingly, binaryen doesn't support all of WAT and
  42. ;; specifically doesn't do implicit stack arguments, so we can't
  43. ;; use br_on_cast as we would like.
  44. (block $Limmediate
  45. (block $Lflonum
  46. (block $Lbignum
  47. (block $Lcomplex
  48. (block $Lfraction
  49. (block $Lpair
  50. (block $Lmutable-pair
  51. (block $Lvector
  52. (block $Lmutable-vector
  53. (block $Lbytevector
  54. (block $Lmutable-bytevector
  55. (block $Lbitvector
  56. (block $Lmutable-bitvector
  57. (block $Lstring
  58. (block $Lmutable-string
  59. (block $Lproc
  60. (block $Lsymbol
  61. (block $Lkeyword
  62. (block $Lvariable
  63. (block $Latomic-box
  64. (block $Lhash-table
  65. (block $Lweak-table
  66. (block $Lfluid
  67. (block $Ldynamic-state
  68. (block $Lsyntax-transformer
  69. (block $Lsyntax
  70. (block $Lport
  71. (block $Lstruct
  72. (block $Lextern-ref
  73. (block $Lcode-ref
  74. (br_if $Limmediate (ref.test i31 (local.get $scm)))
  75. (br_if $Lflonum (ref.test $flonum (local.get $scm)))
  76. (br_if $Lbignum (ref.test $bignum (local.get $scm)))
  77. (br_if $Lcomplex (ref.test $complex (local.get $scm)))
  78. (br_if $Lfraction (ref.test $fraction (local.get $scm)))
  79. (br_if $Lmutable-pair (ref.test $mutable-pair (local.get $scm)))
  80. (br_if $Lpair (ref.test $pair (local.get $scm)))
  81. (br_if $Lmutable-vector (ref.test $mutable-vector (local.get $scm)))
  82. (br_if $Lvector (ref.test $vector (local.get $scm)))
  83. (br_if $Lmutable-bytevector (ref.test $mutable-bytevector (local.get $scm)))
  84. (br_if $Lbytevector (ref.test $bytevector (local.get $scm)))
  85. (br_if $Lmutable-bitvector (ref.test $mutable-bitvector (local.get $scm)))
  86. (br_if $Lbitvector (ref.test $bitvector (local.get $scm)))
  87. (br_if $Lmutable-string (ref.test $mutable-string (local.get $scm)))
  88. (br_if $Lstring (ref.test $string (local.get $scm)))
  89. (br_if $Lproc (ref.test $proc (local.get $scm)))
  90. (br_if $Lsymbol (ref.test $symbol (local.get $scm)))
  91. (br_if $Lkeyword (ref.test $keyword (local.get $scm)))
  92. (br_if $Lvariable (ref.test $variable (local.get $scm)))
  93. (br_if $Latomic-box (ref.test $atomic-box (local.get $scm)))
  94. (br_if $Lhash-table (ref.test $hash-table (local.get $scm)))
  95. (br_if $Lweak-table (ref.test $weak-table (local.get $scm)))
  96. (br_if $Lfluid (ref.test $fluid (local.get $scm)))
  97. (br_if $Ldynamic-state (ref.test $dynamic-state (local.get $scm)))
  98. (br_if $Lsyntax (ref.test $syntax (local.get $scm)))
  99. (br_if $Lsyntax-transformer (ref.test $syntax-transformer (local.get $scm)))
  100. (br_if $Lport (ref.test $port (local.get $scm)))
  101. (br_if $Lstruct (ref.test $struct (local.get $scm)))
  102. (br_if $Lextern-ref (ref.test $extern-ref (local.get $scm)))
  103. (br_if $Lcode-ref (ref.test $code-ref (local.get $scm)))
  104. (unreachable))
  105. (br $Ldone (string.const "code-ref")))
  106. (br $Ldone (string.const "extern-ref")))
  107. (br $Ldone (string.const "struct")))
  108. (br $Ldone (string.const "port")))
  109. (br $Ldone (string.const "syntax")))
  110. (br $Ldone (string.const "syntax-transformer")))
  111. (br $Ldone (string.const "dynamic-state")))
  112. (br $Ldone (string.const "fluid")))
  113. (br $Ldone (string.const "weak-table")))
  114. (br $Ldone (string.const "hash-table")))
  115. (br $Ldone (string.const "atomic-box")))
  116. (br $Ldone (string.const "variable")))
  117. (br $Ldone (string.const "keyword")))
  118. (br $Ldone (string.const "symbol")))
  119. (br $Ldone (string.const "procedure")))
  120. (br $Ldone (string.const "mutable-string")))
  121. (br $Ldone (string.const "string")))
  122. (br $Ldone (string.const "mutable-bitvector")))
  123. (br $Ldone (string.const "bitvector")))
  124. (br $Ldone (string.const "mutable-bytevector")))
  125. (br $Ldone (string.const "bytevector")))
  126. (br $Ldone (string.const "mutable-vector")))
  127. (br $Ldone (string.const "vector")))
  128. (br $Ldone (string.const "mutable-pair")))
  129. (br $Ldone (string.const "pair")))
  130. (br $Ldone (string.const "fraction")))
  131. (br $Ldone (string.const "complex")))
  132. (br $Ldone (string.const "bignum")))
  133. (br $Ldone (string.const "flonum")))
  134. ;; Immediate.
  135. (block $Lfalse
  136. (block $Lnil
  137. (block $Lnull
  138. (block $Ltrue
  139. (block $Lunspecified
  140. (block $Leof
  141. (block $Lundefined
  142. (block $Lchar
  143. (block $Lfixnum
  144. (local.set $tmp (i31.get_s (ref.cast i31 (local.get $scm))))
  145. (br_if $Lfixnum (i32.eqz (i32.and (local.get $tmp) (i32.const 1))))
  146. (br_if $Lchar (i32.eq (i32.and (local.get $tmp) (i32.const 3))
  147. (i32.const 3)))
  148. (br_if $Lfalse (i32.eq (local.get $tmp) (i32.const 1)))
  149. (br_if $Lnil (i32.eq (local.get $tmp) (i32.const 5)))
  150. (br_if $Lnull (i32.eq (local.get $tmp) (i32.const 13)))
  151. (br_if $Ltrue (i32.eq (local.get $tmp) (i32.const 17)))
  152. (br_if $Lunspecified (i32.eq (local.get $tmp) (i32.const 33)))
  153. (br_if $Leof (i32.eq (local.get $tmp) (i32.const 41)))
  154. (br_if $Lundefined (i32.eq (local.get $tmp) (i32.const 57)))
  155. (unreachable))
  156. (br $Ldone (string.const "fixnum")))
  157. (br $Ldone (string.const "char")))
  158. (br $Ldone (string.const "undefined")))
  159. (br $Ldone (string.const "eof")))
  160. (br $Ldone (string.const "unspecified")))
  161. (br $Ldone (string.const "true")))
  162. (br $Ldone (string.const "null")))
  163. (br $Ldone (string.const "nil")))
  164. (br $Ldone (string.const "false"))))
  165. (func $scm-most-negative-fixnum (export "scm_most_negative_fixnum") (result i32)
  166. (i32.const -536870912)) ;; = -0x20000000
  167. (func $scm-most-positive-fixnum (export "scm_most_positive_fixnum") (result i32)
  168. (i32.const 536870911)) ;; = 0x1fffffff
  169. (func $scm-from-fixnum (export "scm_from_fixnum") (param $v i32) (result (ref eq))
  170. (ref.i31 (i32.shl (local.get $v) (i32.const 1))))
  171. (func $scm-from-bignum (export "scm_from_bignum") (param $v (ref extern)) (result (ref eq))
  172. (struct.new $bignum (i32.const 0) (local.get $v)))
  173. (func $scm-from-f64 (export "scm_from_f64") (param $v f64) (result (ref $flonum))
  174. (struct.new $flonum (i32.const 0) (local.get $v)))
  175. (func $scm-false (export "scm_false") (result (ref i31))
  176. (ref.i31 (i32.const 1)))
  177. (func $scm-nil (export "scm_nil") (result (ref i31))
  178. (ref.i31 (i32.const 5)))
  179. (func $scm-null (export "scm_null") (result (ref i31))
  180. (ref.i31 (i32.const 13)))
  181. (func $scm-true (export "scm_true") (result (ref i31))
  182. (ref.i31 (i32.const 17)))
  183. (func $scm-unspecified (export "scm_unspecified") (result (ref i31))
  184. (ref.i31 (i32.const 33)))
  185. (func $scm-eof (export "scm_eof") (result (ref i31))
  186. (ref.i31 (i32.const 41)))
  187. (func $scm-from-char (export "scm_from_char") (param $ch i32) (result (ref i31))
  188. (ref.i31 (i32.or (i32.const 3)
  189. (i32.shl (local.get $ch) (i32.const 2)))))
  190. (func $scm-from-fraction (export "scm_from_fraction") (param (ref eq) (ref eq)) (result (ref $fraction))
  191. ;; FIXME: check types.
  192. (struct.new $fraction (i32.const 0) (local.get 0) (local.get 1)))
  193. (func $scm-from-complex (export "scm_from_complex") (param f64 f64) (result (ref $complex))
  194. ;; FIXME: check types?
  195. (struct.new $complex (i32.const 0) (local.get 0) (local.get 1)))
  196. (func $scm-from-string (export "scm_from_string") (param $str (ref string)) (result (ref $string))
  197. (struct.new $string (i32.const 0) (local.get $str)))
  198. (func $fixnum_value (export "fixnum_value") (param $v (ref i31)) (result i32)
  199. (i32.shr_s (i31.get_s (local.get $v)) (i32.const 1)))
  200. (func $char_value (export "char_value") (param $v (ref i31)) (result i32)
  201. (i32.shr_u (i31.get_s (local.get $v)) (i32.const 2)))
  202. (func $bignum_value (export "bignum_value") (param $v (ref $bignum)) (result (ref extern))
  203. (struct.get $bignum 1 (local.get $v)))
  204. (func $flonum_value (export "flonum_value") (param $v (ref $flonum)) (result f64)
  205. (struct.get $flonum 1 (local.get $v)))
  206. ;; FIXME: Should return 2 values but binaryen doesn't support that :-(
  207. (func $fraction-num (export "fraction_num") (param $v (ref $fraction)) (result (ref eq))
  208. (struct.get $fraction 1 (local.get $v)))
  209. (func $fraction-denom (export "fraction_denom") (param $v (ref $fraction)) (result (ref eq))
  210. (struct.get $fraction 2 (local.get $v)))
  211. ;; FIXME: Should return 2 values but binaryen doesn't support that :-(
  212. (func $complex-real (export "complex_real") (param $v (ref $complex)) (result f64)
  213. (struct.get $complex 1 (local.get $v)))
  214. (func $complex-imag (export "complex_imag") (param $v (ref $complex)) (result f64)
  215. (struct.get $complex 2 (local.get $v)))
  216. (func $string_value (export "string_value") (param $v (ref $string)) (result (ref string))
  217. (struct.get $string 1 (local.get $v)))
  218. (func $symbol_name (export "symbol_name") (param $v (ref $symbol)) (result (ref string))
  219. (call $string_value (struct.get $symbol $name (local.get $v))))
  220. (func $keyword_name (export "keyword_name") (param $v (ref $keyword)) (result (ref string))
  221. (call $symbol_name (struct.get $keyword $name (local.get $v))))
  222. (func $pair_car (export "car") (param $v (ref $pair)) (result (ref eq))
  223. (struct.get $pair 1 (local.get $v)))
  224. (func $pair_cdr (export "cdr") (param $v (ref $pair)) (result (ref eq))
  225. (struct.get $pair 2 (local.get $v)))
  226. (func $push-return (param $k (ref $kvarargs))
  227. (local $sp i32)
  228. (local.set $sp (global.get $ret-sp))
  229. (if (i32.eq (table.size $ret-stack) (local.get $sp))
  230. (then (call $grow-ret-stack
  231. (i32.add (i32.const 16) (local.get $sp)))))
  232. (table.set $ret-stack (local.get $sp) (local.get $k))
  233. (global.set $ret-sp (i32.add (local.get $sp) (i32.const 1))))
  234. (func $make-vector (export "make_vector")
  235. (param $size i32) (param $init (ref eq)) (result (ref $mutable-vector))
  236. (struct.new $mutable-vector
  237. (i32.const 0)
  238. (array.new $raw-scmvector (local.get $init) (local.get $size))))
  239. (func $vector-set (export "vector_set")
  240. (param $vec (ref $mutable-vector)) (param $i i32) (param $val (ref eq))
  241. (array.set $raw-scmvector (struct.get $mutable-vector $vals (local.get $vec))
  242. (local.get $i) (local.get $val)))
  243. (func $vector-ref (export "vector_ref")
  244. (param $vec (ref $vector)) (param $i i32) (result (ref eq))
  245. (array.get $raw-scmvector (struct.get $vector $vals (local.get $vec))
  246. (local.get $i)))
  247. (func $vector-length (export "vector_length")
  248. (param $vec (ref $vector)) (result i32)
  249. (array.len (struct.get $vector $vals (local.get $vec))))
  250. (func $bytevector-set (export "bytevector_set")
  251. (param $vec (ref $mutable-bytevector)) (param $i i32) (param $val i32)
  252. (array.set $raw-bytevector (struct.get $mutable-bytevector $vals (local.get $vec))
  253. (local.get $i) (local.get $val)))
  254. (func $bytevector-ref (export "bytevector_ref")
  255. (param $vec (ref $bytevector)) (param $i i32) (result i32)
  256. (array.get_u $raw-bytevector (struct.get $bytevector $vals (local.get $vec))
  257. (local.get $i)))
  258. (func $bytevector-length (export "bytevector_length")
  259. (param $vec (ref $bytevector)) (result i32)
  260. (array.len (struct.get $bytevector $vals (local.get $vec))))
  261. (func $bitvector-ref (export "bitvector_ref")
  262. (param $vec (ref $bitvector)) (param $i i32) (result i32)
  263. (i32.and
  264. (i32.shr_u
  265. (array.get $raw-bitvector (struct.get $bitvector $vals (local.get $vec))
  266. (i32.shr_u (local.get $i) (i32.const 5)))
  267. (local.get $i))
  268. (i32.const 1)))
  269. (func $bitvector-length (export "bitvector_length")
  270. (param $vec (ref $bitvector)) (result i32)
  271. (struct.get $bitvector $len (local.get $vec)))
  272. (func $extern-value (export "extern_value")
  273. (param $ext (ref $extern-ref)) (result (ref null extern))
  274. (struct.get $extern-ref $val (local.get $ext)))
  275. (func $scm-from-extern (export "scm_from_extern")
  276. (param $ext (ref null extern)) (result (ref eq))
  277. (struct.new $extern-ref (i32.const 0) (local.get $ext)))
  278. (func $code-value (export "code_value")
  279. (param $code (ref $code-ref)) (result (ref func))
  280. (struct.get $code-ref $val (local.get $code)))
  281. (func $scm-from-code (export "scm_from_code")
  282. (param $code (ref func)) (result (ref eq))
  283. (struct.new $code-ref (i32.const 0) (local.get $code)))
  284. (global $return-values (mut (ref null $raw-scmvector)) (ref.null $raw-scmvector))
  285. (func $save-values-and-return-to-host (param $nargs i32)
  286. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  287. (local $i i32)
  288. (local $ret (ref $raw-scmvector))
  289. (local.set $ret (array.new $raw-scmvector (ref.i31 (i32.const 1))
  290. (local.get $nargs)))
  291. (block $nargs0
  292. (block $nargs1
  293. (block $nargs2
  294. (block $nargs3
  295. (block $nargs4
  296. (block $nargs5
  297. (block $nargs6
  298. (block $nargs7
  299. (block $nargs8
  300. (block $nargsN
  301. (br_table $nargs0
  302. $nargs1
  303. $nargs2
  304. $nargs3
  305. $nargs4
  306. $nargs5
  307. $nargs6
  308. $nargs7
  309. $nargs8
  310. $nargsN
  311. (local.get $nargs)))
  312. (local.set $i (i32.const 8))
  313. (loop
  314. (array.set $raw-scmvector (local.get $ret) (local.get $i)
  315. (ref.as_non_null
  316. (table.get $argv
  317. (i32.sub (local.get $i) (i32.const 8)))))
  318. (local.set $i (i32.add (local.get $i) (i32.const 1)))
  319. (br_if 0 (i32.lt_s (local.get $i) (local.get $nargs)))))
  320. (array.set $raw-scmvector (local.get $ret) (i32.const 7)
  321. (global.get $arg7)))
  322. (array.set $raw-scmvector (local.get $ret) (i32.const 6)
  323. (global.get $arg6)))
  324. (array.set $raw-scmvector (local.get $ret) (i32.const 5)
  325. (global.get $arg5)))
  326. (array.set $raw-scmvector (local.get $ret) (i32.const 4)
  327. (global.get $arg4)))
  328. (array.set $raw-scmvector (local.get $ret) (i32.const 3)
  329. (global.get $arg3)))
  330. (array.set $raw-scmvector (local.get $ret) (i32.const 2)
  331. (local.get $arg2)))
  332. (array.set $raw-scmvector (local.get $ret) (i32.const 1)
  333. (local.get $arg1)))
  334. (array.set $raw-scmvector (local.get $ret) (i32.const 0)
  335. (local.get $arg0)))
  336. (global.set $return-values (local.get $ret)))
  337. ;; Pop the top of the dynamic stack and tail call the continuation
  338. ;; waiting on the return stack.
  339. (func $pop-dyn-and-continue
  340. (param $nargs i32)
  341. (param $arg0 (ref eq))
  342. (param $arg1 (ref eq))
  343. (param $arg2 (ref eq))
  344. (global.set $dyn-sp (i32.sub (global.get $dyn-sp) (i32.const 1)))
  345. (global.set $ret-sp (i32.sub (global.get $ret-sp) (i32.const 1)))
  346. (return_call_ref $kvarargs
  347. (local.get $nargs)
  348. (local.get $arg0)
  349. (local.get $arg1)
  350. (local.get $arg2)
  351. (table.get $ret-stack (global.get $ret-sp))))
  352. ;; A duplication of default-prompt-handler in (hoot control) but in
  353. ;; Wasm. Receives a continuation and a procedure and then calls the
  354. ;; procedure with the continuation as its sole argument.
  355. (func $default-prompt-handler
  356. (param $nargs i32)
  357. (param $arg0 (ref eq))
  358. (param $arg1 (ref eq))
  359. (param $arg2 (ref eq))
  360. (call $push-default-prompt)
  361. (return_call_ref $kvarargs
  362. (i32.const 2)
  363. (local.get $arg1) ; proc
  364. (local.get $arg0) ; cont
  365. (ref.i31 (i32.const 1))
  366. (struct.get $proc $func
  367. (ref.cast $proc (local.get $arg1)))))
  368. ;; Push the default prompt with default handler, for call/cc.
  369. (func $push-default-prompt
  370. (call $push-dyn
  371. (struct.new $dynprompt
  372. (global.get $raw-sp)
  373. (global.get $scm-sp)
  374. (global.get $ret-sp)
  375. (i32.const 0)
  376. (call $fluid-ref
  377. (struct.get $parameter $fluid
  378. (ref.cast $parameter
  379. (global.get $default-prompt-tag))))
  380. (ref.func $default-prompt-handler)))
  381. (call $push-return (ref.func $pop-dyn-and-continue)))
  382. (func $call-with-trampoline
  383. (param $nargs i32)
  384. (param $arg0 (ref eq))
  385. (param $arg1 (ref eq))
  386. (param $arg2 (ref eq))
  387. (param $func (ref $kvarargs))
  388. (local $begin-ret-sp i32)
  389. ;; Make a note of the height of the return stack. We'll use
  390. ;; this to determine if a 'catch' is in the right context to
  391. ;; perform the trampoline.
  392. (local.set $begin-ret-sp (global.get $ret-sp))
  393. (call $push-default-prompt)
  394. (loop $loop
  395. (try $handler
  396. (do (call_ref $kvarargs
  397. (local.get $nargs)
  398. (local.get $arg0)
  399. (local.get $arg1)
  400. (local.get $arg2)
  401. (local.get $func)))
  402. (catch $trampoline-tag
  403. ;; The number of return continuations pushed by
  404. ;; the thrower is on top of the stack at this
  405. ;; point, hence the single additional operand
  406. ;; below.
  407. (i32.add (local.get $begin-ret-sp))
  408. ;; It's possible that we are in a nested 'try'
  409. ;; block due to re-entrance into the Hoot ABI.
  410. ;; The correct 'catch' block is determined by
  411. ;; comparing the height of the return stack upon
  412. ;; entry to the current height of the return
  413. ;; stack. If the height upon entry is greater,
  414. ;; then we must rethrow in search of the proper
  415. ;; handler.
  416. (if (param i32 (ref eq) (ref eq) (ref eq) (ref $kvarargs))
  417. (i32.gt_s (global.get $ret-sp))
  418. (then
  419. (rethrow $handler))
  420. (else
  421. ;; The 'throw' to the $trampoline-tag tag
  422. ;; pushed a procedure call onto the stack
  423. ;; that resumes the continuation.
  424. ;; Reconfigure our locals and iterate to
  425. ;; call it in the context of a new exception
  426. ;; handler.
  427. (local.set $func)
  428. (local.set $arg2)
  429. (local.set $arg1)
  430. (local.set $arg0)
  431. (local.set $nargs)
  432. (br $loop)))))))
  433. (func $call (export "call")
  434. (param $proc (ref $proc)) (param $args (ref $vector))
  435. (result (ref $vector))
  436. (local $arg0 (ref eq))
  437. (local $arg1 (ref eq))
  438. (local $arg2 (ref eq))
  439. (local $vals (ref $raw-scmvector))
  440. (local $i i32)
  441. (local.set $vals (struct.get $vector $vals (local.get $args)))
  442. (local.set $arg0 (ref.i31 (i32.const 0)))
  443. (local.set $arg1 (ref.i31 (i32.const 0)))
  444. (local.set $arg2 (ref.i31 (i32.const 0)))
  445. (block $nargs0
  446. (block $nargs1
  447. (block $nargs2
  448. (block $nargs3
  449. (block $nargs4
  450. (block $nargs5
  451. (block $nargs6
  452. (block $nargs7
  453. (block $nargs8
  454. (block $nargsN
  455. (br_table $nargs0
  456. $nargs1
  457. $nargs2
  458. $nargs3
  459. $nargs4
  460. $nargs5
  461. $nargs6
  462. $nargs7
  463. $nargs8
  464. $nargsN
  465. (array.len (local.get $vals))))
  466. (local.set $i (i32.const 8))
  467. (if (i32.lt_u (table.size $argv)
  468. (i32.sub (array.len (local.get $vals))
  469. (i32.const 8)))
  470. (then
  471. (call $grow-argv (array.len (local.get $vals)))))
  472. (loop
  473. (table.set $argv
  474. (i32.sub (local.get $i) (i32.const 8))
  475. (array.get $raw-scmvector
  476. (local.get $vals) (local.get $i)))
  477. (local.set $i (i32.add (local.get $i) (i32.const 1)))
  478. (br_if 0 (i32.lt_s (local.get $i)
  479. (array.len (local.get $vals))))))
  480. (global.set $arg7 (array.get $raw-scmvector
  481. (local.get $vals) (i32.const 7))))
  482. (global.set $arg6 (array.get $raw-scmvector
  483. (local.get $vals) (i32.const 6))))
  484. (global.set $arg5 (array.get $raw-scmvector
  485. (local.get $vals) (i32.const 5))))
  486. (global.set $arg4 (array.get $raw-scmvector
  487. (local.get $vals) (i32.const 4))))
  488. (global.set $arg3 (array.get $raw-scmvector
  489. (local.get $vals) (i32.const 3))))
  490. (local.set $arg2 (array.get $raw-scmvector
  491. (local.get $vals) (i32.const 2))))
  492. (local.set $arg1 (array.get $raw-scmvector
  493. (local.get $vals) (i32.const 1))))
  494. (local.set $arg0 (array.get $raw-scmvector
  495. (local.get $vals) (i32.const 0))))
  496. (call $push-return (ref.func $save-values-and-return-to-host))
  497. (call $call-with-trampoline
  498. (array.len (local.get $vals))
  499. (local.get $arg0) (local.get $arg1) (local.get $arg2)
  500. (struct.get $proc $func (local.get $proc)))
  501. (local.set $vals (ref.as_non_null (global.get $return-values)))
  502. (global.set $return-values (ref.null $raw-scmvector))
  503. (struct.new $vector (i32.const 0) (local.get $vals)))
  504. )