basic-types.wat 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. (module
  2. (type $kvarargs
  3. (func (param $nargs i32)
  4. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))))
  5. (type $raw-bitvector (array (mut i32)))
  6. (type $raw-bytevector (array (mut i8)))
  7. (type $raw-scmvector (array (mut (ref eq))))
  8. (rec
  9. (type $heap-object
  10. (sub
  11. (struct
  12. (field $hash (mut i32)))))
  13. (type $extern-ref
  14. (sub $heap-object
  15. (struct
  16. (field $hash (mut i32))
  17. (field $val (ref extern)))))
  18. (type $bignum
  19. (sub $heap-object
  20. (struct
  21. (field $hash (mut i32))
  22. (field $val (ref extern)))))
  23. (type $flonum
  24. (sub $heap-object
  25. (struct
  26. (field $hash (mut i32))
  27. (field $val f64))))
  28. (type $complex
  29. (sub $heap-object
  30. (struct
  31. (field $hash (mut i32))
  32. (field $real f64)
  33. (field $imag f64))))
  34. (type $fraction
  35. (sub $heap-object
  36. (struct
  37. (field $hash (mut i32))
  38. (field $num (ref eq))
  39. (field $denom (ref eq)))))
  40. (type $pair
  41. (sub $heap-object
  42. (struct
  43. (field $hash (mut i32))
  44. (field $car (mut (ref eq)))
  45. (field $cdr (mut (ref eq))))))
  46. (type $mutable-pair
  47. (sub $pair
  48. (struct
  49. (field $hash (mut i32))
  50. (field $car (mut (ref eq)))
  51. (field $cdr (mut (ref eq))))))
  52. (type $vector
  53. (sub $heap-object
  54. (struct
  55. (field $hash (mut i32))
  56. (field $vals (ref $raw-scmvector)))))
  57. (type $mutable-vector
  58. (sub $vector
  59. (struct
  60. (field $hash (mut i32))
  61. (field $vals (ref $raw-scmvector)))))
  62. (type $bytevector
  63. (sub $heap-object
  64. (struct
  65. (field $hash (mut i32))
  66. (field $vals (ref $raw-bytevector)))))
  67. (type $mutable-bytevector
  68. (sub $bytevector
  69. (struct
  70. (field $hash (mut i32))
  71. (field $vals (ref $raw-bytevector)))))
  72. (type $bitvector
  73. (sub $heap-object
  74. (struct
  75. (field $hash (mut i32))
  76. (field $len i32)
  77. (field $vals (ref $raw-bitvector)))))
  78. (type $mutable-bitvector
  79. (sub $bitvector
  80. (struct
  81. (field $hash (mut i32))
  82. (field $len i32)
  83. (field $vals (ref $raw-bitvector)))))
  84. (type $string
  85. (sub $heap-object
  86. (struct
  87. (field $hash (mut i32))
  88. (field $str (ref string)))))
  89. (type $mutable-string
  90. (sub $string
  91. (struct
  92. (field $hash (mut i32))
  93. (field $str (ref string)))))
  94. (type $proc
  95. (sub $heap-object
  96. (struct
  97. (field $hash (mut i32))
  98. (field $func (ref $kvarargs)))))
  99. (type $symbol
  100. (sub $heap-object
  101. (struct
  102. (field $hash (mut i32))
  103. (field $name (ref $string)))))
  104. (type $keyword
  105. (sub $heap-object
  106. (struct
  107. (field $hash (mut i32))
  108. (field $name (ref $symbol)))))
  109. (type $variable
  110. (sub $heap-object
  111. (struct
  112. (field $hash (mut i32))
  113. (field $val (mut (ref eq))))))
  114. (type $atomic-box
  115. (sub $heap-object
  116. (struct
  117. (field $hash (mut i32))
  118. (field $val (mut (ref eq))))))
  119. (type $hash-table
  120. (sub $heap-object
  121. (struct
  122. (field $hash (mut i32))
  123. (field $size (mut i32))
  124. (field $buckets (ref $raw-scmvector)))))
  125. (type $weak-table
  126. (sub $heap-object
  127. (struct
  128. (field $hash (mut i32))
  129. (field $val (ref extern)))))
  130. (type $fluid
  131. (sub $heap-object
  132. (struct
  133. (field $hash (mut i32))
  134. (field $init (ref eq)))))
  135. (type $dynamic-state
  136. (sub $heap-object
  137. (struct
  138. (field $hash (mut i32))
  139. (field $val (ref extern)))))
  140. (type $syntax
  141. (sub $heap-object
  142. (struct
  143. (field $hash (mut i32))
  144. (field $expr (ref eq))
  145. (field $wrap (ref eq))
  146. (field $module (ref eq))
  147. (field $source (ref eq)))))
  148. (type $port-type
  149. (struct
  150. (field $name (ref string))
  151. ;; in guile these are (port, bv, start, count) -> size_t
  152. (field $read (ref null $proc)) ;; could have a more refined type
  153. (field $write (ref null $proc))
  154. (field $seek (ref null $proc)) ;; (port, offset, whence) -> offset
  155. (field $close (ref null $proc)) ;; (port) -> ()
  156. (field $get-natural-buffer-sizes (ref null $proc)) ;; port -> (rdsz, wrsz)
  157. (field $random-access? (ref null $proc)) ;; port -> bool
  158. (field $input-waiting (ref null $proc)) ;; port -> bool
  159. (field $truncate (ref null $proc)) ;; (port, length) -> ()
  160. ;; Guile also has GOOPS classes here.
  161. ))
  162. (type $port
  163. (sub $heap-object
  164. (struct
  165. (field $hash (mut i32))
  166. (field $pt (ref $port-type))
  167. (field $stream (mut (ref eq)))
  168. (field $file_name (mut (ref eq)))
  169. (field $position (ref $pair))
  170. (field $read_buf (mut (ref eq))) ;; A 5-vector
  171. (field $write_buf (mut (ref eq))) ;; A 5-vector
  172. (field $write_buf_aux (mut (ref eq))) ;; A 5-vector
  173. (field $read_buffering (mut i32))
  174. (field $refcount (mut i32))
  175. (field $rw_random (mut i8))
  176. (field $properties (mut (ref eq))))))
  177. (type $struct
  178. (sub $heap-object
  179. (struct
  180. (field $hash (mut i32))
  181. ;; Vtable link is mutable so that we can tie the knot for top
  182. ;; types.
  183. (field $vtable (mut (ref null $vtable))))))
  184. (type $vtable
  185. (sub $struct
  186. (struct
  187. (field $hash (mut i32))
  188. (field $vtable (mut (ref null $vtable)))
  189. (field $field0 (mut (ref eq)))
  190. (field $field1 (mut (ref eq)))
  191. (field $field2 (mut (ref eq)))
  192. (field $field3 (mut (ref eq)))))))
  193. (type $struct1
  194. (sub $struct
  195. (struct
  196. (field $hash (mut i32))
  197. (field $vtable (mut (ref null $vtable)))
  198. (field $field0 (mut (ref eq))))))
  199. (type $struct2
  200. (sub $struct
  201. (struct
  202. (field $hash (mut i32))
  203. (field $vtable (mut (ref null $vtable)))
  204. (field $field0 (mut (ref eq)))
  205. (field $field1 (mut (ref eq))))))
  206. (type $struct3
  207. (sub $struct
  208. (struct
  209. (field $hash (mut i32))
  210. (field $vtable (mut (ref null $vtable)))
  211. (field $field0 (mut (ref eq)))
  212. (field $field1 (mut (ref eq)))
  213. (field $field2 (mut (ref eq))))))
  214. (type $struct4
  215. (sub $struct
  216. (struct
  217. (field $hash (mut i32))
  218. (field $vtable (mut (ref null $vtable)))
  219. (field $field0 (mut (ref eq)))
  220. (field $field1 (mut (ref eq)))
  221. (field $field2 (mut (ref eq)))
  222. (field $field3 (mut (ref eq))))))
  223. (type $structN
  224. (sub $struct
  225. (struct
  226. (field $hash (mut i32))
  227. (field $vtable (mut (ref null $vtable)))
  228. (field $field0 (mut (ref eq)))
  229. (field $field1 (mut (ref eq)))
  230. (field $field2 (mut (ref eq)))
  231. (field $field3 (mut (ref eq)))
  232. (field $tail (ref $raw-scmvector)))))
  233. ;; $arg0, $arg1, $arg2: function parameters
  234. (global $arg3 (mut (ref eq)) (ref.i31 (i32.const 0)))
  235. (global $arg4 (mut (ref eq)) (ref.i31 (i32.const 0)))
  236. (global $arg5 (mut (ref eq)) (ref.i31 (i32.const 0)))
  237. (global $arg6 (mut (ref eq)) (ref.i31 (i32.const 0)))
  238. (global $arg7 (mut (ref eq)) (ref.i31 (i32.const 0)))
  239. ;; FIXME: Probably we should have non-nullable types here but binaryen
  240. ;; doesn't support it.
  241. (table $argv 0 (ref null eq))
  242. (global $return-sp (mut i32) (i32.const 0))
  243. ;; FIXME: Non-nullable.
  244. (table $return-stack 0 (ref null $kvarargs))
  245. ;; These grow functions try to grow their corresponding tables,
  246. ;; filling in a sensible default value so as to not require the
  247. ;; tables to be nullable, and abort if that fails.
  248. (func $grow-argv (param $diff i32)
  249. (br_if 0 (i32.ge_s (i32.const 0)
  250. (table.grow $argv (ref.null i31)
  251. (local.get $diff))))
  252. (unreachable))
  253. (func $grow-return-stack (param $diff i32)
  254. (br_if 0 (i32.ge_s (i32.const 0)
  255. (table.grow $return-stack (ref.null $kvarargs)
  256. (local.get $diff))))
  257. (unreachable))
  258. (func $%make-struct1 (param (ref null $vtable) (ref eq))
  259. (result (ref $struct1))
  260. (struct.new $struct1 (i32.const 0) (local.get 0) (local.get 1)))
  261. (func $%make-struct2 (param (ref null $vtable) (ref eq) (ref eq))
  262. (result (ref $struct2))
  263. (struct.new $struct2 (i32.const 0) (local.get 0) (local.get 1) (local.get 2)))
  264. (func $%make-struct3 (param (ref null $vtable) (ref eq) (ref eq) (ref eq))
  265. (result (ref $struct3))
  266. (struct.new $struct3 (i32.const 0) (local.get 0) (local.get 1) (local.get 2) (local.get 3)))
  267. (func $%make-struct4 (param (ref null $vtable) (ref eq) (ref eq) (ref eq) (ref eq))
  268. (result (ref $struct4))
  269. (struct.new $struct4 (i32.const 0) (local.get 0)
  270. (local.get 1) (local.get 2) (local.get 3) (local.get 4)))
  271. (func $%make-vtable (param (ref null $vtable) (ref eq) (ref eq) (ref eq) (ref eq))
  272. (result (ref $vtable))
  273. (struct.new $vtable (i32.const 0) (local.get 0)
  274. (local.get 1) (local.get 2) (local.get 3) (local.get 4)))
  275. (func $%make-simple-vtable
  276. (param $vt (ref null $vtable)) (param $flags i32) (param $nfields i32)
  277. (result (ref $vtable))
  278. (call $%make-vtable
  279. (local.get $vt)
  280. ;; field 0: flags: fixnum
  281. (ref.i31 (i32.shl (local.get $flags) (i32.const 1)))
  282. ;; field 1: nfields: fixnum
  283. (ref.i31 (i32.shl (local.get $nfields) (i32.const 1)))
  284. ;; field 2: name: #f
  285. (ref.i31 (i32.const 1))
  286. ;; field 3: print: #f
  287. (ref.i31 (i32.const 1))))
  288. (global $root-vtable (mut (ref null $vtable)) (ref.null $vtable))
  289. (func $%init-structs
  290. (global.set $root-vtable
  291. (call $%make-simple-vtable
  292. (ref.null $vtable)
  293. (i32.const 3) ;; flags: validated | vtable-vtable
  294. (i32.const 4))) ;; 4 fields
  295. ;; Tie the knot.
  296. (struct.set $vtable 1 (global.get $root-vtable) (global.get $root-vtable)))
  297. ;; When the module is instantiated, grow a new default-sized $argv and
  298. ;; $return-stack.
  299. (func $start
  300. (call $grow-argv (i32.const 42))
  301. (call $grow-return-stack (i32.const 42))
  302. (call $%init-structs)
  303. (call $%init-keywords)
  304. (call $%init-ports))
  305. (start $start)
  306. (func $describe (export "describe") (param $scm (ref eq)) (result (ref string))
  307. (local $tmp i32)
  308. (block $Ldone (result (ref string))
  309. ;; Verrrrry annoyingly, binaryen doesn't support all of WAT and
  310. ;; specifically doesn't do implicit stack arguments, so we can't
  311. ;; use br_on_cast as we would like.
  312. (block $Limmediate
  313. (block $Lflonum
  314. (block $Lbignum
  315. (block $Lcomplex
  316. (block $Lfraction
  317. (block $Lpair
  318. (block $Lmutable-pair
  319. (block $Lvector
  320. (block $Lmutable-vector
  321. (block $Lbytevector
  322. (block $Lmutable-bytevector
  323. (block $Lbitvector
  324. (block $Lmutable-bitvector
  325. (block $Lstring
  326. (block $Lmutable-string
  327. (block $Lproc
  328. (block $Lsymbol
  329. (block $Lkeyword
  330. (block $Lvariable
  331. (block $Latomic-box
  332. (block $Lhash-table
  333. (block $Lweak-table
  334. (block $Lfluid
  335. (block $Ldynamic-state
  336. (block $Lsyntax
  337. (block $Lport
  338. (block $Lstruct
  339. (br_if $Limmediate (ref.test i31 (local.get $scm)))
  340. (br_if $Lflonum (ref.test $flonum (local.get $scm)))
  341. (br_if $Lbignum (ref.test $bignum (local.get $scm)))
  342. (br_if $Lcomplex (ref.test $complex (local.get $scm)))
  343. (br_if $Lfraction (ref.test $fraction (local.get $scm)))
  344. (br_if $Lmutable-pair (ref.test $mutable-pair (local.get $scm)))
  345. (br_if $Lpair (ref.test $pair (local.get $scm)))
  346. (br_if $Lmutable-vector (ref.test $mutable-vector (local.get $scm)))
  347. (br_if $Lvector (ref.test $vector (local.get $scm)))
  348. (br_if $Lmutable-bytevector (ref.test $mutable-bytevector (local.get $scm)))
  349. (br_if $Lbytevector (ref.test $bytevector (local.get $scm)))
  350. (br_if $Lmutable-bitvector (ref.test $mutable-bitvector (local.get $scm)))
  351. (br_if $Lbitvector (ref.test $bitvector (local.get $scm)))
  352. (br_if $Lmutable-string (ref.test $mutable-string (local.get $scm)))
  353. (br_if $Lstring (ref.test $string (local.get $scm)))
  354. (br_if $Lproc (ref.test $proc (local.get $scm)))
  355. (br_if $Lsymbol (ref.test $symbol (local.get $scm)))
  356. (br_if $Lkeyword (ref.test $keyword (local.get $scm)))
  357. (br_if $Lvariable (ref.test $variable (local.get $scm)))
  358. (br_if $Latomic-box (ref.test $atomic-box (local.get $scm)))
  359. (br_if $Lhash-table (ref.test $hash-table (local.get $scm)))
  360. (br_if $Lweak-table (ref.test $weak-table (local.get $scm)))
  361. (br_if $Lfluid (ref.test $fluid (local.get $scm)))
  362. (br_if $Ldynamic-state (ref.test $dynamic-state (local.get $scm)))
  363. (br_if $Lsyntax (ref.test $syntax (local.get $scm)))
  364. (br_if $Lport (ref.test $port (local.get $scm)))
  365. (br_if $Lstruct (ref.test $struct (local.get $scm)))
  366. (unreachable))
  367. (br $Ldone (string.const "struct")))
  368. (br $Ldone (string.const "port")))
  369. (br $Ldone (string.const "syntax")))
  370. (br $Ldone (string.const "dynamic-state")))
  371. (br $Ldone (string.const "fluid")))
  372. (br $Ldone (string.const "weak-table")))
  373. (br $Ldone (string.const "hash-table")))
  374. (br $Ldone (string.const "atomic-box")))
  375. (br $Ldone (string.const "variable")))
  376. (br $Ldone (string.const "keyword")))
  377. (br $Ldone (string.const "symbol")))
  378. (br $Ldone (string.const "procedure")))
  379. (br $Ldone (string.const "mutable-string")))
  380. (br $Ldone (string.const "string")))
  381. (br $Ldone (string.const "mutable-bitvector")))
  382. (br $Ldone (string.const "bitvector")))
  383. (br $Ldone (string.const "mutable-bytevector")))
  384. (br $Ldone (string.const "bytevector")))
  385. (br $Ldone (string.const "mutable-vector")))
  386. (br $Ldone (string.const "vector")))
  387. (br $Ldone (string.const "mutable-pair")))
  388. (br $Ldone (string.const "pair")))
  389. (br $Ldone (string.const "fraction")))
  390. (br $Ldone (string.const "complex")))
  391. (br $Ldone (string.const "bignum")))
  392. (br $Ldone (string.const "flonum")))
  393. ;; Immediate.
  394. (block $Lfalse
  395. (block $Lnil
  396. (block $Lnull
  397. (block $Ltrue
  398. (block $Lunspecified
  399. (block $Leof
  400. (block $Lchar
  401. (block $Lfixnum
  402. (local.set $tmp (i31.get_s (ref.cast i31 (local.get $scm))))
  403. (br_if $Lfixnum (i32.eqz (i32.and (local.get $tmp) (i32.const 1))))
  404. (br_if $Lchar (i32.eq (i32.and (local.get $tmp) (i32.const 2))
  405. (i32.const 2)))
  406. (br_if $Lfalse (i32.eq (local.get $tmp) (i32.const 1)))
  407. (br_if $Lnil (i32.eq (local.get $tmp) (i32.const 5)))
  408. (br_if $Lnull (i32.eq (local.get $tmp) (i32.const 13)))
  409. (br_if $Ltrue (i32.eq (local.get $tmp) (i32.const 17)))
  410. (br_if $Lunspecified (i32.eq (local.get $tmp) (i32.const 33)))
  411. (br_if $Leof (i32.eq (local.get $tmp) (i32.const 41)))
  412. (unreachable))
  413. (br $Ldone (string.const "fixnum")))
  414. (br $Ldone (string.const "char")))
  415. (br $Ldone (string.const "eof")))
  416. (br $Ldone (string.const "unspecified")))
  417. (br $Ldone (string.const "true")))
  418. (br $Ldone (string.const "null")))
  419. (br $Ldone (string.const "nil")))
  420. (br $Ldone (string.const "false"))))
  421. (func $get-argument (import "rt" "get_argument")
  422. (param i32) (result (ref eq)))
  423. (func $prepare-return-values (import "rt" "prepare_return_values")
  424. (param i32))
  425. (func $set-return-value (import "rt" "set_return_value")
  426. (param i32 (ref eq)))
  427. (func $bignum-from-i64 (import "rt" "bignum_from_i64")
  428. (param i64) (result (ref extern)))
  429. (func $bignum-from-u64 (import "rt" "bignum_from_u64")
  430. (param i64) (result (ref extern)))
  431. (func $bignum-is-i64 (import "rt" "bignum_is_i64")
  432. (param (ref extern)) (result i32))
  433. (func $bignum-is-u64 (import "rt" "bignum_is_u64")
  434. (param (ref extern)) (result i32))
  435. (func $bignum-get-i64 (import "rt" "bignum_get_i64")
  436. (param (ref extern)) (result i64))
  437. (func $make-weak-map (import "rt" "make_weak_map")
  438. (result (ref extern)))
  439. (func $weak-map-get (import "rt" "weak_map_get")
  440. (param (ref extern)) (result (ref null eq)))
  441. (func $weak-map-set (import "rt" "weak_map_set")
  442. (param (ref extern) (ref eq) (ref eq)))
  443. (func $weak-map-delete (import "rt" "weak_map_delete")
  444. (param (ref extern) (ref eq)) (result i32))
  445. (func $scm-from-f64 (export "scm_from_f64") (param $v f64) (result (ref $flonum))
  446. (struct.new $flonum (i32.const 0) (local.get $v)))
  447. (func $scm-from-integer (export "scm_from_integer") (param $v (ref extern)) (result (ref eq))
  448. (local $tmp i64)
  449. (block $Lbignum
  450. (br_if $Lbignum (i32.eqz (call $bignum-is-i64 (local.get $v))))
  451. (local.set $tmp (call $bignum-get-i64 (local.get $v)))
  452. ;; 536870912 = 0x2000_0000, 1073741824 = 0x4000_0000
  453. (br_if $Lbignum (i64.gt_u (i64.add (i64.const 536870912)
  454. (local.get $tmp))
  455. (i64.const 1073741824)))
  456. (br 1 (ref.i31 (i32.wrap_i64 (local.get $tmp)))))
  457. (struct.new $bignum (i32.const 0) (local.get $v)))
  458. (func $scm-false (export "scm_false") (result (ref i31))
  459. (ref.i31 (i32.const 1)))
  460. (func $scm-nil (export "scm_nil") (result (ref i31))
  461. (ref.i31 (i32.const 5)))
  462. (func $scm-null (export "scm_null") (result (ref i31))
  463. (ref.i31 (i32.const 13)))
  464. (func $scm-true (export "scm_true") (result (ref i31))
  465. (ref.i31 (i32.const 17)))
  466. (func $scm-unspecified (export "scm_unspecified") (result (ref i31))
  467. (ref.i31 (i32.const 33)))
  468. (func $scm-eof (export "scm_eof") (result (ref i31))
  469. (ref.i31 (i32.const 41)))
  470. (func $scm-from-char (export "scm_from_char") (param $ch i32) (result (ref i31))
  471. (ref.i31 (i32.and (i32.const 3)
  472. (i32.shl (local.get $ch) (i32.const 2)))))
  473. (func $scm-from-fraction (export "scm_from_fraction") (param (ref eq) (ref eq)) (result (ref $fraction))
  474. ;; FIXME: check types.
  475. (struct.new $fraction (i32.const 0) (local.get 0) (local.get 1)))
  476. (func $scm-from-complex (export "scm_from_complex") (param f64 f64) (result (ref $complex))
  477. ;; FIXME: check types?
  478. (struct.new $complex (i32.const 0) (local.get 0) (local.get 1)))
  479. (func $scm-from-string (export "scm_from_string") (param $str (ref string)) (result (ref $string))
  480. (struct.new $string (i32.const 0) (local.get $str)))
  481. (func $fixnum_value (export "fixnum_value") (param $v (ref i31)) (result i32)
  482. (i32.shr_s (i31.get_s (local.get $v)) (i32.const 1)))
  483. (func $char_value (export "char_value") (param $v (ref i31)) (result i32)
  484. (i32.shr_u (i31.get_s (local.get $v)) (i32.const 2)))
  485. (func $bignum_value (export "bignum_value") (param $v (ref $bignum)) (result (ref extern))
  486. (struct.get $bignum 1 (local.get $v)))
  487. (func $flonum_value (export "flonum_value") (param $v (ref $flonum)) (result f64)
  488. (struct.get $flonum 1 (local.get $v)))
  489. ;; FIXME: Should return 2 values but binaryen doesn't support that :-(
  490. (func $fraction-num (export "fraction_num") (param $v (ref $fraction)) (result (ref eq))
  491. (struct.get $fraction 1 (local.get $v)))
  492. (func $fraction-denom (export "fraction_denom") (param $v (ref $fraction)) (result (ref eq))
  493. (struct.get $fraction 2 (local.get $v)))
  494. ;; FIXME: Should return 2 values but binaryen doesn't support that :-(
  495. (func $complex-real (export "complex_real") (param $v (ref $complex)) (result f64)
  496. (struct.get $complex 1 (local.get $v)))
  497. (func $complex-imag (export "complex_imag") (param $v (ref $complex)) (result f64)
  498. (struct.get $complex 2 (local.get $v)))
  499. (func $string_value (export "string_value") (param $v (ref $string)) (result (ref string))
  500. (struct.get $string 1 (local.get $v)))
  501. (func $pair_car (export "car") (param $v (ref $pair)) (result (ref eq))
  502. (struct.get $pair 1 (local.get $v)))
  503. (func $pair_cdr (export "cdr") (param $v (ref $pair)) (result (ref eq))
  504. (struct.get $pair 2 (local.get $v)))
  505. (func $push-return (param $k (ref $kvarargs))
  506. (table.set $return-stack (global.get $return-sp) (local.get $k))
  507. (global.set $return-sp (i32.add (global.get $return-sp) (i32.const 1))))
  508. (func $pop-return (result (ref $kvarargs))
  509. (global.set $return-sp (i32.sub (global.get $return-sp) (i32.const 1)))
  510. (ref.as_non_null (table.get $return-stack (global.get $return-sp))))
  511. ;; Thomas Wang's integer hasher, from
  512. ;; http://www.cris.com/~Ttwang/tech/inthash.htm.
  513. (func $integer-hash (param $v i32) (result i32)
  514. (local.set $v (i32.xor (i32.xor (local.get $v) (i32.const 61))
  515. (i32.shr_u (local.get $v) (i32.const 16))))
  516. (local.set $v (i32.add (local.get $v)
  517. (i32.shl (local.get $v) (i32.const 3))))
  518. (local.set $v (i32.xor (local.get $v)
  519. (i32.shr_u (local.get $v) (i32.const 4))))
  520. (local.set $v (i32.mul (local.get $v)
  521. (i32.const 668265261))) ;; = 0x27d4eb2d
  522. (i32.xor (local.get $v)
  523. (i32.shr_u (local.get $v) (i32.const 15))))
  524. ;; Mix hash bits. Result must be nonzero.
  525. (func $finish-heap-object-hash (param $hash i32) (result i32)
  526. (local.set $hash (call $integer-hash (local.get $hash)))
  527. (if i32 (local.get $hash)
  528. (then (local.get $hash))
  529. (else (call $integer-hash (i32.const 42)))))
  530. (global $hashq-counter (mut i32) (i32.const 0))
  531. (func $%hashq (param $v (ref eq)) (result i32)
  532. (local $obj (ref $heap-object))
  533. (local $tag i32)
  534. (block $Limmediate
  535. (br_if $Limmediate (ref.test i31 (local.get $v)))
  536. (local.set $obj (ref.cast $heap-object (local.get $v)))
  537. (local.set $tag (struct.get $heap-object 0 (local.get $obj)))
  538. (block $Linitialized
  539. (br_if $Linitialized (local.get $tag))
  540. (global.set $hashq-counter
  541. (i32.sub (global.get $hashq-counter) (i32.const 1)))
  542. (local.set $tag
  543. (call $finish-heap-object-hash (global.get $hashq-counter)))
  544. (struct.set $heap-object 0 (local.get $obj) (local.get $tag)))
  545. (br 1 (local.get $tag)))
  546. (call $integer-hash (i31.get_u (ref.cast i31 (local.get $v)))))
  547. ;; For now, the Java string hash function, except over codepoints
  548. ;; rather than WTF-16 code units.
  549. (func $string-hash (param $str (ref string)) (result i32)
  550. (local $iter (ref stringview_iter))
  551. (local $hash i32)
  552. (local $codepoint i32)
  553. (local.set $iter (string.as_iter (local.get $str)))
  554. (block $done
  555. (loop $lp
  556. (local.set $codepoint (stringview_iter.next (local.get $iter)))
  557. (br_if $done (i32.eq (i32.const -1) (local.get $codepoint)))
  558. (local.set $hash
  559. (i32.add (i32.mul (local.get $hash) (i32.const 31))
  560. (local.get $codepoint)))
  561. (br $lp)))
  562. (local.get $hash))
  563. (type $symtab-entry
  564. (struct (field $sym (ref $symbol)) (field $next (ref null $symtab-entry))))
  565. (type $symtab (array (mut (ref null $symtab-entry))))
  566. (global $the-symtab (ref $symtab)
  567. (array.new $symtab (ref.null $symtab-entry) (i32.const 47)))
  568. (func $string-to-symbol (param $str (ref string)) (result (ref $symbol))
  569. (local $hash i32)
  570. (local $idx i32)
  571. (local $tag i32)
  572. (local $entry (ref null $symtab-entry))
  573. (local $ret (ref null $symbol))
  574. (local.set $hash (call $string-hash (local.get $str)))
  575. (local.set $idx (i32.rem_u (local.get $hash) (array.len (global.get $the-symtab))))
  576. (local.set $tag (call $finish-heap-object-hash (local.get $hash)))
  577. (local.set $entry (array.get $symtab (global.get $the-symtab) (local.get $idx)))
  578. (block $done
  579. (block $insert
  580. (loop $lp
  581. (br_if $insert (ref.is_null (local.get $entry)))
  582. (block $next
  583. (br_if $next
  584. (i32.ne (struct.get $symbol 0
  585. (struct.get $symtab-entry 0 (local.get $entry)))
  586. (local.get $tag)))
  587. (br_if $next
  588. (i32.eqz
  589. (string.eq (struct.get $string 1
  590. (struct.get $symbol 1
  591. (struct.get $symtab-entry 0
  592. (local.get $entry))))
  593. (local.get $str))))
  594. (local.set $ret (struct.get $symtab-entry 0 (local.get $entry)))
  595. (br $done))
  596. (local.set $entry (struct.get $symtab-entry 1 (local.get $entry)))
  597. (br $lp)))
  598. (local.set $ret (struct.new $symbol (local.get $tag)
  599. (struct.new $string (i32.const 0) (local.get $str))))
  600. (local.set $entry (array.get $symtab (global.get $the-symtab) (local.get $idx)))
  601. (array.set $symtab (global.get $the-symtab) (local.get $idx)
  602. (struct.new $symtab-entry (ref.as_non_null (local.get $ret))
  603. (local.get $entry))))
  604. (ref.as_non_null (local.get $ret)))
  605. (func $%make-hash-table (result (ref $hash-table))
  606. (struct.new $hash-table (i32.const 0) (i32.const 0)
  607. (array.new $raw-scmvector
  608. (ref.i31 (i32.const 13)) (i32.const 47))))
  609. (func $%hashq-lookup (param $tab (ref $hash-table)) (param $k (ref eq))
  610. (result (ref null $pair))
  611. (local $idx i32)
  612. (local $buckets (ref $raw-scmvector))
  613. (local $chain (ref eq))
  614. (local $head (ref $pair))
  615. (local.set $buckets (struct.get $hash-table $buckets (local.get $tab)))
  616. (local.set $idx (i32.rem_u (call $%hashq (local.get $k))
  617. (array.len (local.get $buckets))))
  618. (local.set $chain (array.get $raw-scmvector (local.get $buckets) (local.get $idx)))
  619. (block $not-found
  620. (loop $lp
  621. (br_if $not-found (i32.eqz (ref.test $pair (local.get $chain))))
  622. (local.set $head
  623. (ref.cast $pair (struct.get $pair 1
  624. (ref.cast $pair (local.get $chain)))))
  625. (local.set $chain (struct.get $pair 2 (ref.cast $pair (local.get $chain))))
  626. (block $found
  627. (br_if $found
  628. (ref.eq (struct.get $pair 1 (local.get $head))
  629. (local.get $k)))
  630. (br $lp))
  631. (br 2 (local.get $head))))
  632. (ref.null $pair))
  633. (func $%hashq-insert (param $tab (ref $hash-table)) (param $k (ref eq)) (param $v (ref eq))
  634. (local $idx i32)
  635. (local $buckets (ref $raw-scmvector))
  636. (local.set $buckets (struct.get $hash-table $buckets (local.get $tab)))
  637. (local.set $idx (i32.rem_u (call $%hashq (local.get $k))
  638. (array.len (local.get $buckets))))
  639. (array.set $raw-scmvector
  640. (local.get $buckets) (local.get $idx)
  641. (struct.new $pair (i32.const 0)
  642. (struct.new $pair (i32.const 0) (local.get $k) (local.get $v))
  643. (array.get $raw-scmvector (local.get $buckets) (local.get $idx))))
  644. (struct.set $hash-table $size
  645. (local.get $tab)
  646. (i32.add (i32.const 1)
  647. (struct.get $hash-table $size (local.get $tab)))))
  648. (global $the-kwtab (mut (ref null $hash-table)) (ref.null $hash-table))
  649. (func $%init-keywords
  650. (global.set $the-kwtab (call $%make-hash-table)))
  651. (func $symbol-to-keyword (param $sym (ref $symbol)) (result (ref $keyword))
  652. (local $entry (ref null $pair))
  653. (local $new-kw (ref $keyword))
  654. (local.set $entry (call $%hashq-lookup
  655. (ref.as_non_null (global.get $the-kwtab))
  656. (local.get $sym)))
  657. (block $not-found
  658. (br_if $not-found (ref.is_null (local.get $entry)))
  659. (br 1 (ref.cast $keyword (struct.get $pair 2 (local.get $entry)))))
  660. (local.set $new-kw
  661. (struct.new $keyword
  662. (call $finish-heap-object-hash
  663. (struct.get $symbol 0 (local.get $sym)))
  664. (local.get $sym)))
  665. (call $%hashq-insert
  666. (ref.as_non_null (global.get $the-kwtab))
  667. (local.get $sym)
  668. (local.get $new-kw))
  669. (local.get $new-kw))
  670. ;; Things like this should be implemented in Scheme.
  671. (type $string-input-port-stream
  672. (struct (field $bv (ref $raw-bytevector))
  673. (field $pos (mut i32))))
  674. (func $string-input-port-read (param $nargs i32)
  675. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  676. (local $port (ref $port))
  677. (local $dst (ref $raw-bytevector))
  678. (local $start i32)
  679. (local $count i32)
  680. (local $stream (ref $string-input-port-stream))
  681. (local $src (ref $raw-bytevector))
  682. (local $pos i32)
  683. (local $avail i32)
  684. (local $i i32)
  685. (block $check-nargs
  686. (br_if $check-nargs (i32.eq (local.get $nargs) (i32.const 4)))
  687. (unreachable))
  688. (local.set $port (ref.cast $port (local.get $arg0)))
  689. (local.set $dst (struct.get $bytevector 1
  690. (ref.cast $bytevector (local.get $arg1))))
  691. (local.set $start (i31.get_s (ref.cast i31 (local.get $arg2))))
  692. (local.set $count (i31.get_s (ref.cast i31 (global.get $arg3))))
  693. (local.set $stream (ref.cast $string-input-port-stream
  694. (struct.get $port $stream (local.get $port))))
  695. (local.set $src (struct.get $string-input-port-stream 0 (local.get $stream)))
  696. (local.set $pos (struct.get $string-input-port-stream 1 (local.get $stream)))
  697. (local.set $avail
  698. (i32.sub (array.len (local.get $src)) (local.get $pos)))
  699. (block $trim
  700. (br_if $trim (i32.lt_s (local.get $count) (local.get $avail)))
  701. (local.set $count (local.get $avail)))
  702. (block $done
  703. (loop $lp
  704. (br_if $done (i32.eq (local.get $i) (local.get $count)))
  705. (array.set $raw-bytevector
  706. (local.get $dst)
  707. (i32.add (local.get $start) (local.get $i))
  708. (array.get_u $raw-bytevector (local.get $src)
  709. (i32.add (local.get $pos) (local.get $i))))
  710. (local.set $i (i32.add (local.get $i) (i32.const 1)))
  711. (br $lp)))
  712. (struct.set $string-input-port-stream 1 (local.get $stream)
  713. (i32.add (local.get $pos) (local.get $count)))
  714. (return_call_ref $kvarargs
  715. (i32.const 1) ;; nargs
  716. (ref.i31 (local.get $count))
  717. (ref.i31 (i32.const 0)) ;; filler
  718. (ref.i31 (i32.const 0)) ;; filler
  719. (call $pop-return)))
  720. (func $string-input-port-seek (param $nargs i32)
  721. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  722. ;; Not yet implemented.
  723. (unreachable))
  724. (func $string-input-port-random-access? (param $nargs i32)
  725. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  726. ;; Not yet implemented.
  727. (unreachable))
  728. (func $string-input-port-input-waiting? (param $nargs i32)
  729. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  730. ;; Not yet implemented.
  731. (unreachable))
  732. (func $string-output-port-write (param $nargs i32)
  733. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  734. ;; Not yet implemented.
  735. (unreachable))
  736. (global $string-input-port-type (mut (ref null $port-type)) (ref.null $port-type))
  737. (global $string-output-port-type (mut (ref null $port-type)) (ref.null $port-type))
  738. (func $%init-ports
  739. (global.set
  740. $string-input-port-type
  741. (struct.new
  742. $port-type
  743. (string.const "string-input-port")
  744. (struct.new $proc (i32.const 0) (ref.func $string-input-port-read))
  745. (ref.null $proc) ;; write
  746. (struct.new $proc (i32.const 0) (ref.func $string-input-port-seek))
  747. (ref.null $proc) ;; close
  748. (ref.null $proc) ;; get-natural-buffer-sizes
  749. (struct.new $proc (i32.const 0) (ref.func $string-input-port-random-access?))
  750. (struct.new $proc (i32.const 0) (ref.func $string-input-port-input-waiting?))
  751. (ref.null $proc) ;; truncate
  752. ))
  753. (global.set
  754. $string-output-port-type
  755. (struct.new
  756. $port-type
  757. (string.const "string-output-port")
  758. (ref.null $proc) ;; read
  759. (struct.new $proc (i32.const 0) (ref.func $string-output-port-write)) ;; write
  760. (ref.null $proc) ;; seek
  761. (ref.null $proc) ;; close
  762. (ref.null $proc) ;; get-natural-buffer-sizes
  763. (ref.null $proc) ;; random-access?
  764. (ref.null $proc) ;; input-waiting?
  765. (ref.null $proc) ;; truncate
  766. )))
  767. (func $%make-string-input-port (param $str (ref string)) (result (ref $port))
  768. (local $wtf8 (ref $raw-bytevector))
  769. ;; FIXME!!!!! Binaryen borks measure_utf8 and measure_wtf8
  770. (local.set $wtf8
  771. (array.new_default $raw-bytevector (string.measure_wtf16 (local.get $str))))
  772. ;; FIXME!!! binaryen borks this too
  773. ;; (string.encode_lossy_utf8_array (local.get $str) (local.get $wtf8) (i32.const 0))
  774. (struct.new $port (i32.const 0)
  775. (ref.cast $port-type (global.get $string-input-port-type))
  776. (struct.new $string-input-port-stream
  777. (local.get $wtf8)
  778. (i32.const 0))
  779. (ref.i31 (i32.const 1)) ;; file_name
  780. ;; position: (cons 0 0)
  781. (struct.new $mutable-pair (i32.const 0)
  782. (ref.i31 (i32.const 0)) (ref.i31 (i32.const 0)))
  783. (ref.i31 (i32.const 1)) ;; read buf: #f
  784. (ref.i31 (i32.const 1)) ;; write buf: #f
  785. (ref.i31 (i32.const 1)) ;; write buf aux: #f
  786. (i32.const 0) ;; read-buffering
  787. (i32.const 0) ;; refcount
  788. (i32.const 0) ;; rw_random ?
  789. (ref.i31 (i32.const 13)) ;; properties: ()
  790. ))
  791. (func $main (param $nargs i32)
  792. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  793. ;; Fixnum: 1.
  794. (local.set $arg0 (ref.i31 (i32.const 2)))
  795. ;; Char: 1.
  796. (local.set $arg1 (ref.i31 (i32.const 7)))
  797. ;; False.
  798. (local.set $arg2 (ref.i31 (i32.const 1)))
  799. ;; Null.
  800. (global.set $arg3 (ref.i31 (i32.const 13)))
  801. ;; True.
  802. (global.set $arg4 (ref.i31 (i32.const 17)))
  803. ;; Unspecified.
  804. (global.set $arg5 (ref.i31 (i32.const 33)))
  805. ;; EOF.
  806. (global.set $arg6 (ref.i31 (i32.const 41)))
  807. ;; '(1 . 2)
  808. (global.set $arg7
  809. (struct.new $pair (i32.const 0)
  810. (ref.i31 (i32.const 2)) (ref.i31 (i32.const 4))))
  811. ;; (cons 1 2)
  812. (table.set $argv (i32.const 0)
  813. (struct.new $mutable-pair (i32.const 0)
  814. (ref.i31 (i32.const 2)) (ref.i31 (i32.const 4))))
  815. ;; #(#f #f #f)
  816. (table.set $argv (i32.const 1)
  817. (struct.new $vector (i32.const 0)
  818. (array.new $raw-scmvector (ref.i31 (i32.const 1)) (i32.const 3))))
  819. ;; (vector #f #f #f)
  820. (table.set $argv (i32.const 2)
  821. (struct.new $mutable-vector (i32.const 0)
  822. (array.new $raw-scmvector (ref.i31 (i32.const 1)) (i32.const 3))))
  823. ;; #vu8(0 0 0 0 0)
  824. (table.set $argv (i32.const 3)
  825. (struct.new $bytevector (i32.const 0)
  826. (array.new_default $raw-bytevector (i32.const 5))))
  827. ;; (bytevector 0 0 0 0 0)
  828. (table.set $argv (i32.const 4)
  829. (struct.new $mutable-bytevector (i32.const 0)
  830. (array.new_default $raw-bytevector (i32.const 5))))
  831. ;; #*11111
  832. (table.set $argv (i32.const 5)
  833. (struct.new $bitvector (i32.const 0)
  834. (i32.const 5)
  835. (array.new $raw-bitvector (i32.const 31) (i32.const 1))))
  836. ;; (bitvector #t #t #t #t #t)
  837. (table.set $argv (i32.const 6)
  838. (struct.new $mutable-bitvector (i32.const 0)
  839. (i32.const 5)
  840. (array.new $raw-bitvector (i32.const 31) (i32.const 1))))
  841. ;; "hello world!"
  842. (table.set $argv (i32.const 7)
  843. (struct.new $string (i32.const 0)
  844. (string.const "hello world!")))
  845. ;; (string #\h #\e #\l #\l #\o #\o)
  846. (table.set $argv (i32.const 8)
  847. (struct.new $mutable-string (i32.const 0)
  848. (string.const "helloo")))
  849. ;; #<procedure main>
  850. (table.set $argv (i32.const 9)
  851. (struct.new $proc (i32.const 0) (ref.func $main)))
  852. ;; 'my-symbol
  853. (table.set $argv (i32.const 10)
  854. (call $string-to-symbol (string.const "my-symbol")))
  855. ;; #:my-symbol
  856. (table.set $argv (i32.const 11)
  857. (call $symbol-to-keyword
  858. (call $string-to-symbol (string.const "my-symbol"))))
  859. ;; (make-variable #f)
  860. (table.set $argv (i32.const 12)
  861. (struct.new $variable (i32.const 17) (ref.i31 (i32.const 1))))
  862. ;; (make-atomic-box #f)
  863. (table.set $argv (i32.const 13)
  864. (struct.new $atomic-box (i32.const 18) (ref.i31 (i32.const 1))))
  865. ;; (make-hash-table)
  866. (table.set $argv (i32.const 14)
  867. (call $%make-hash-table))
  868. ;; (make-weak-key-hash-table)
  869. (table.set $argv (i32.const 15)
  870. (struct.new $weak-table (i32.const 0) (call $make-weak-map)))
  871. ;; (make-struct (make-vtable 1) #f)
  872. (table.set $argv (i32.const 16)
  873. (call $%make-struct1
  874. (call $%make-simple-vtable
  875. (global.get $root-vtable)
  876. ;; flags: validated
  877. (i32.const 1)
  878. ;; one field
  879. (i32.const 1))
  880. (ref.i31 (i32.const 1))))
  881. ;; 42.69
  882. (table.set $argv (i32.const 17)
  883. (struct.new $flonum (i32.const 0) (f64.const 42.69)))
  884. ;; 1<<31
  885. (table.set $argv (i32.const 18)
  886. (struct.new $bignum (i32.const 0)
  887. ;; 2147483648 = 0x80000000
  888. (call $bignum-from-i64 (i64.const 2147483648))))
  889. ;; 42+6.9i
  890. (table.set $argv (i32.const 19)
  891. (struct.new $complex (i32.const 0)
  892. (f64.const 42) (f64.const 6.9)))
  893. ;; 14/23
  894. (table.set $argv (i32.const 20)
  895. (struct.new $fraction (i32.const 0)
  896. (ref.i31 (i32.const 28))
  897. (ref.i31 (i32.const 46))))
  898. ;; (make-fluid #f)
  899. (table.set $argv (i32.const 21)
  900. (struct.new $fluid (i32.const 0) (ref.i31 (i32.const 1))))
  901. ;; (current-dynamic-state)
  902. (table.set $argv (i32.const 22)
  903. (struct.new $dynamic-state (i32.const 0)
  904. (call $make-weak-map)))
  905. ;; (datum->syntax #f '() #:source #f)
  906. (table.set $argv (i32.const 23)
  907. (struct.new $syntax (i32.const 0)
  908. (ref.i31 (i32.const 13)) ;; datum: ()
  909. (struct.new $pair (i32.const 0)
  910. (ref.i31 (i32.const 13))
  911. (ref.i31 (i32.const 13))) ;; wrap: empty-wrap: (())
  912. (ref.i31 (i32.const 1)) ;; module: #f
  913. (ref.i31 (i32.const 1)) ;; source: #f
  914. ))
  915. ;; (current-input-port)
  916. (table.set $argv (i32.const 24)
  917. (call $%make-string-input-port (string.const "hey!!!")))
  918. (return_call_ref $kvarargs
  919. (i32.const 33)
  920. (local.get $arg0)
  921. (local.get $arg1)
  922. (local.get $arg2)
  923. (call $pop-return)))
  924. (func $return-to-host (param $nargs i32)
  925. (param $arg0 (ref eq)) (param $arg1 (ref eq)) (param $arg2 (ref eq))
  926. (local $i i32)
  927. (call $prepare-return-values (local.get $nargs))
  928. (block $nargs0
  929. (block $nargs1
  930. (block $nargs2
  931. (block $nargs3
  932. (block $nargs4
  933. (block $nargs5
  934. (block $nargs6
  935. (block $nargs7
  936. (block $nargs8
  937. (block $nargsN
  938. (br_table $nargs0
  939. $nargs1
  940. $nargs2
  941. $nargs3
  942. $nargs4
  943. $nargs5
  944. $nargs6
  945. $nargs7
  946. $nargs8
  947. $nargsN
  948. (local.get $nargs)))
  949. (local.set $i (i32.const 8))
  950. (loop
  951. (call $set-return-value
  952. (local.get $i)
  953. (ref.as_non_null
  954. (table.get $argv
  955. (i32.sub (local.get $i) (i32.const 8)))))
  956. (local.set $i (i32.add (local.get $i) (i32.const 1)))
  957. (br_if 0 (i32.lt_s (local.get $i) (local.get $nargs)))))
  958. (call $set-return-value (i32.const 7) (global.get $arg7)))
  959. (call $set-return-value (i32.const 6) (global.get $arg6)))
  960. (call $set-return-value (i32.const 5) (global.get $arg5)))
  961. (call $set-return-value (i32.const 4) (global.get $arg4)))
  962. (call $set-return-value (i32.const 3) (global.get $arg3)))
  963. (call $set-return-value (i32.const 2) (local.get $arg2)))
  964. (call $set-return-value (i32.const 1) (local.get $arg1)))
  965. (call $set-return-value (i32.const 0) (local.get $arg0))))
  966. (func $init (export "_init") (param $nargs i32)
  967. (local $arg0 (ref eq))
  968. (local $arg1 (ref eq))
  969. (local $arg2 (ref eq))
  970. (local $i i32)
  971. (local.set $arg0 (ref.i31 (i32.const 0)))
  972. (local.set $arg1 (ref.i31 (i32.const 0)))
  973. (local.set $arg2 (ref.i31 (i32.const 0)))
  974. (block $nargs0
  975. (block $nargs1
  976. (block $nargs2
  977. (block $nargs3
  978. (block $nargs4
  979. (block $nargs5
  980. (block $nargs6
  981. (block $nargs7
  982. (block $nargs8
  983. (block $nargsN
  984. (br_table $nargs0
  985. $nargs1
  986. $nargs2
  987. $nargs3
  988. $nargs4
  989. $nargs5
  990. $nargs6
  991. $nargs7
  992. $nargs8
  993. $nargsN
  994. (local.get $nargs)))
  995. (local.set $i (i32.const 8))
  996. (loop
  997. (table.set $argv
  998. (i32.sub (local.get $i) (i32.const 8))
  999. (call $get-argument (local.get $i)))
  1000. (local.set $i (i32.add (local.get $i) (i32.const 1)))
  1001. (br_if 0 (i32.lt_s (local.get $i) (local.get $nargs)))))
  1002. (global.set $arg7 (call $get-argument (i32.const 7))))
  1003. (global.set $arg6 (call $get-argument (i32.const 6))))
  1004. (global.set $arg5 (call $get-argument (i32.const 5))))
  1005. (global.set $arg4 (call $get-argument (i32.const 4))))
  1006. (global.set $arg3 (call $get-argument (i32.const 3))))
  1007. (local.set $arg2 (call $get-argument (i32.const 2))))
  1008. (local.set $arg1 (call $get-argument (i32.const 1))))
  1009. (local.set $arg0 (call $get-argument (i32.const 0))))
  1010. (call $push-return (ref.func $return-to-host))
  1011. (return_call $main (local.get $nargs)
  1012. (local.get $arg0) (local.get $arg1) (local.get $arg2))))