parse.scm 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. ;;; WebAssembly binary parser
  2. ;;; Copyright (C) 2023 Igalia, S.L.
  3. ;;; Copyright (C) 2024 David Thompson <dave@spritely.institute>
  4. ;;;
  5. ;;; Licensed under the Apache License, Version 2.0 (the "License");
  6. ;;; you may not use this file except in compliance with the License.
  7. ;;; You may obtain a copy of the License at
  8. ;;;
  9. ;;; http://www.apache.org/licenses/LICENSE-2.0
  10. ;;;
  11. ;;; Unless required by applicable law or agreed to in writing, software
  12. ;;; distributed under the License is distributed on an "AS IS" BASIS,
  13. ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ;;; See the License for the specific language governing permissions and
  15. ;;; limitations under the License.
  16. ;;; Commentary:
  17. ;;;
  18. ;;; Parser for WebAssembly binary format
  19. ;;;
  20. ;;; Code:
  21. (define-module (wasm parse)
  22. #:use-module (ice-9 binary-ports)
  23. #:use-module (ice-9 match)
  24. #:use-module (rnrs bytevectors)
  25. #:use-module (srfi srfi-11)
  26. #:use-module (wasm types)
  27. #:export (parse-wasm))
  28. (define (parse-wasm port)
  29. (define (match-u8 port u8)
  30. (match (lookahead-u8 port)
  31. ((? (lambda (x) (eqv? x u8))) (get-u8 port))
  32. (_ #f)))
  33. (define (expect-u8 port u8)
  34. (unless (match-u8 port u8)
  35. (error "unexpected byte" u8 (get-u8 port))))
  36. (define (get-uleb port)
  37. (let lp ((n 0) (shift 0))
  38. (let ((b (get-u8 port)))
  39. (if (zero? (logand b #x80))
  40. (logior (ash b shift) n)
  41. (lp (logior (ash (logxor #x80 b) shift) n)
  42. (+ shift 7))))))
  43. (define (get-sleb port)
  44. (let lp ((n 0) (shift 0))
  45. (let ((b (get-u8 port)))
  46. (if (zero? (logand b #x80))
  47. (logior (ash b shift) n
  48. (if (zero? (logand #x40 b))
  49. 0
  50. (- (ash 1 (+ shift 7)))))
  51. (lp (logior (ash (logxor #x80 b) shift) n)
  52. (+ shift 7))))))
  53. (define (get-bytes port n)
  54. (let ((bytes (get-bytevector-n port n)))
  55. (unless (eqv? (bytevector-length bytes) n)
  56. (error "unexpected EOF while reading bytes"))
  57. bytes))
  58. (define (get-name port)
  59. (let* ((len (get-uleb port))
  60. (bytes (get-bytes port len)))
  61. (utf8->string bytes)))
  62. (define (parse-vec port parse-one)
  63. (let lp ((n (get-uleb port)))
  64. (if (zero? n)
  65. '()
  66. (let ((item (parse-one port)))
  67. (cons item (lp (1- n)))))))
  68. (define (parse-vec/u8 port)
  69. (get-bytes port (get-uleb port)))
  70. (define (parse-heap-type port)
  71. (cond
  72. ((match-u8 port #x73) 'nofunc)
  73. ((match-u8 port #x72) 'noextern)
  74. ((match-u8 port #x71) 'none)
  75. ((match-u8 port #x70) 'func)
  76. ((match-u8 port #x6F) 'extern)
  77. ((match-u8 port #x6E) 'any)
  78. ((match-u8 port #x6D) 'eq)
  79. ((match-u8 port #x6C) 'i31)
  80. ((match-u8 port #x6B) 'struct)
  81. ((match-u8 port #x6A) 'array)
  82. ((match-u8 port #x67) 'string)
  83. ((match-u8 port #x66) 'stringview_wtf8)
  84. ((match-u8 port #x62) 'stringview_wtf16)
  85. ((match-u8 port #x61) 'stringview_iter)
  86. (else
  87. (let ((val (get-sleb port)))
  88. (when (negative? val) (error "unexpected negative heap type" val))
  89. val))))
  90. (define (parse-val-type port)
  91. (match (get-u8 port)
  92. (#x7F 'i32)
  93. (#x7E 'i64)
  94. (#x7D 'f32)
  95. (#x7C 'f64)
  96. (#x7B 'v128)
  97. (#x73 'nullfuncref)
  98. (#x72 'nullexternref)
  99. (#x71 'nullref)
  100. (#x70 'funcref)
  101. (#x6F 'externref)
  102. (#x6E 'anyref)
  103. (#x6D 'eqref)
  104. (#x6C 'i31ref)
  105. (#x6B 'structref)
  106. (#x6A 'arrayref)
  107. (#x64 (make-ref-type #f (parse-heap-type port)))
  108. (#x63 (make-ref-type #t (parse-heap-type port)))
  109. (#x67 'stringref)
  110. (#x66 'stringview_wtf8ref)
  111. (#x62 'stringview_wtf16ref)
  112. (#x61 'stringview_iterref)
  113. (byte (error "unexpected byte" byte))))
  114. (define (parse-ref-type port)
  115. (match (parse-val-type port)
  116. ((and numeric (or 'i32 'i64 'f32 'f64 'v128))
  117. (error "unexpected numeric type" numeric))
  118. (type type)))
  119. (define (parse-limits port)
  120. (match (get-u8 port)
  121. (#x00 (make-limits (get-uleb port) #f))
  122. (#x01 (let ((min (get-uleb port)))
  123. (make-limits min (get-uleb port))))
  124. (byte (error "unexpected byte byte"))))
  125. (define (parse-types port)
  126. (define (parse-storage-type port)
  127. (cond
  128. ((match-u8 port #x78) 'i8)
  129. ((match-u8 port #x77) 'i16)
  130. (else (parse-val-type port))))
  131. (define (parse-field-def port)
  132. (let ((type (parse-storage-type port)))
  133. (make-field #f
  134. (match (get-u8 port)
  135. (#x00 #f)
  136. (#x01 #t)
  137. (byte (error "unexpected mutability" byte)))
  138. type)))
  139. (define (parse-base-type port)
  140. (match (get-u8 port)
  141. (#x5E (match (parse-field-def port)
  142. (($ <field> #f mutable? type)
  143. (make-array-type mutable? type))))
  144. (#x5F (make-struct-type (parse-vec port parse-field-def)))
  145. (#x60 (let* ((params (map (lambda (type)
  146. (make-param #f type))
  147. (parse-vec port parse-val-type)))
  148. (results (parse-vec port parse-val-type)))
  149. (make-func-sig params results)))
  150. (byte (error "unexpected" byte))))
  151. (define (parse-sub-type port)
  152. (make-type #f (cond
  153. ((match-u8 port #x4F)
  154. (let ((supers (parse-vec port get-uleb)))
  155. (make-sub-type #t supers (parse-base-type port))))
  156. ((match-u8 port #x50)
  157. (let ((supers (parse-vec port get-uleb)))
  158. (make-sub-type #f supers (parse-base-type port))))
  159. (else (parse-base-type port)))))
  160. (define (parse-rec-group port)
  161. (if (match-u8 port #x4E)
  162. (make-rec-group (parse-vec port parse-sub-type))
  163. (parse-sub-type port)))
  164. (parse-vec port parse-rec-group))
  165. (define (parse-type-use port)
  166. (let ((idx (get-uleb port)))
  167. (make-type-use idx #f)))
  168. (define (parse-table-type port)
  169. (let* ((type (parse-ref-type port))
  170. (limits (parse-limits port)))
  171. (make-table-type limits type)))
  172. (define (parse-mem-type port)
  173. (make-mem-type (parse-limits port)))
  174. (define (parse-global-type port)
  175. (let ((type (parse-val-type port)))
  176. (match (get-u8 port)
  177. (#x00 (make-global-type #f type))
  178. (#x01 (make-global-type #t type))
  179. (byte (error "unexpected byte" byte)))))
  180. (define (parse-tag-type port)
  181. (match (get-u8 port)
  182. (#x00 (make-tag-type 'exception (parse-type-use port)))
  183. (byte (error "unexpected byte" byte))))
  184. (define (parse-imports port)
  185. (define (parse-import port)
  186. (let* ((mod (get-name port))
  187. (name (get-name port)))
  188. (match (get-u8 port)
  189. (#x00 (make-import mod name 'func #f (parse-type-use port)))
  190. (#x01 (make-import mod name 'table #f (parse-table-type port)))
  191. (#x02 (make-import mod name 'memory #f (parse-mem-type port)))
  192. (#x03 (make-import mod name 'global #f (parse-global-type port)))
  193. (#x04 (make-import mod name 'tag #f (parse-tag-type port)))
  194. (byte (error "unexpected byte" byte)))))
  195. (parse-vec port parse-import))
  196. (define (parse-func-decls port)
  197. (parse-vec port parse-type-use))
  198. (define (parse-expr port)
  199. (define (parse-idx) (get-uleb port))
  200. (define (parse-block-type)
  201. (cond
  202. ((match-u8 port #x40) #f)
  203. ((= #x40 (logand #xc0 (lookahead-u8 port))) (parse-val-type port))
  204. (else (get-sleb port))))
  205. (define (parse-mem-arg)
  206. (let* ((align* (get-uleb port))
  207. (align (logand align* (lognot (ash 1 6))))
  208. (idx (if (logtest align* (ash 1 6))
  209. (get-uleb port)
  210. 0))
  211. (offset (get-uleb port)))
  212. (make-mem-arg 0 offset align)))
  213. (define (parse-body*)
  214. (let lp ((insts '()))
  215. (define (k inst)
  216. (lp (cons inst insts)))
  217. (match (get-u8 port)
  218. (#x0B (values (reverse insts) 'end))
  219. (#x05 (values (reverse insts) 'else))
  220. (#x07 (values (reverse insts) 'catch))
  221. (#x18 (values (reverse insts) 'delegate))
  222. (#x19 (values (reverse insts) 'catch_all))
  223. (#x00 (k `(unreachable)))
  224. (#x01 (k `(nop)))
  225. (#x02 (let* ((type (parse-block-type))
  226. (body (parse-body)))
  227. (k `(block #f ,type ,body))))
  228. (#x03 (let* ((type (parse-block-type))
  229. (body (parse-body)))
  230. (k `(loop #f ,type ,body))))
  231. (#x04 (let*-values (((type) (parse-block-type))
  232. ((consequent end-tok) (parse-body*)))
  233. (match end-tok
  234. ('end (k `(if #f ,type ,consequent ())))
  235. ('else (k `(if #f ,type ,consequent ,(parse-body))))
  236. (_ (error "unexpected token" end-tok)))))
  237. (#x06 (let*-values (((type) (parse-block-type))
  238. ((body end-tok) (parse-body*)))
  239. (let lp ((catches '()) (end-tok end-tok))
  240. (match end-tok
  241. ('end
  242. (k `(try #f ,type ,body ,(reverse catches) #f)))
  243. ('catch
  244. (let ((tag-idx (parse-idx)))
  245. (let-values (((catch end-tok) (parse-body*)))
  246. (lp (cons (cons tag-idx catch) catches) end-tok))))
  247. ('catch_all
  248. (let-values (((catch-all end-tok) (parse-body*)))
  249. (unless (eq? end-tok 'end)
  250. (error "expected end after catch_all" end-tok))
  251. (k `(try #f ,type ,body ,(reverse catches)
  252. ,catch-all))))
  253. ('delegate
  254. (unless (null? catches)
  255. (error "can't delegate with catches"))
  256. (k `(try_delegate #f ,type ,body ,(parse-idx))))
  257. (_ (error "unexpected token" end-tok))))))
  258. (#x08 (k `(throw ,(parse-idx))))
  259. (#x09 (k `(rethrow ,(parse-idx))))
  260. (#x0c (k `(br ,(parse-idx))))
  261. (#x0d (k `(br_if ,(parse-idx))))
  262. (#x0e (let ((targets (parse-vec port get-uleb)))
  263. (k `(br_table ,targets ,(parse-idx)))))
  264. (#x0f (k `(return)))
  265. (#x10 (k `(call ,(parse-idx))))
  266. (#x11 (let* ((type (parse-idx))
  267. (table (parse-idx)))
  268. (k `(call_indirect ,table ,type))))
  269. (#x12 (k `(return_call ,(parse-idx))))
  270. (#x13 (let* ((type (parse-idx))
  271. (table (parse-idx)))
  272. (k `(return_call_indirect ,table ,type))))
  273. (#x14 (k `(call_ref ,(parse-idx))))
  274. (#x15 (k `(return_call_ref ,(parse-idx))))
  275. (#x1a (k `(drop)))
  276. (#x1b (k `(select)))
  277. (#x1c (k `(select ,(parse-vec port parse-val-type))))
  278. (#x20 (k `(local.get ,(parse-idx))))
  279. (#x21 (k `(local.set ,(parse-idx))))
  280. (#x22 (k `(local.tee ,(parse-idx))))
  281. (#x23 (k `(global.get ,(parse-idx))))
  282. (#x24 (k `(global.set ,(parse-idx))))
  283. (#x25 (k `(table.get ,(parse-idx))))
  284. (#x26 (k `(table.set ,(parse-idx))))
  285. (#x28 (k `(i32.load ,(parse-mem-arg))))
  286. (#x29 (k `(i64.load ,(parse-mem-arg))))
  287. (#x2a (k `(f32.load ,(parse-mem-arg))))
  288. (#x2b (k `(f64.load ,(parse-mem-arg))))
  289. (#x2c (k `(i32.load8_s ,(parse-mem-arg))))
  290. (#x2d (k `(i32.load8_u ,(parse-mem-arg))))
  291. (#x2e (k `(i32.load16_s ,(parse-mem-arg))))
  292. (#x2f (k `(i32.load16_u ,(parse-mem-arg))))
  293. (#x30 (k `(i64.load8_s ,(parse-mem-arg))))
  294. (#x31 (k `(i64.load8_u ,(parse-mem-arg))))
  295. (#x32 (k `(i64.load16_s ,(parse-mem-arg))))
  296. (#x33 (k `(i64.load16_u ,(parse-mem-arg))))
  297. (#x34 (k `(i64.load32_s ,(parse-mem-arg))))
  298. (#x35 (k `(i64.load32_u ,(parse-mem-arg))))
  299. (#x36 (k `(i32.store ,(parse-mem-arg))))
  300. (#x37 (k `(i64.store ,(parse-mem-arg))))
  301. (#x38 (k `(f32.store ,(parse-mem-arg))))
  302. (#x39 (k `(f64.store ,(parse-mem-arg))))
  303. (#x3a (k `(i32.store8 ,(parse-mem-arg))))
  304. (#x3b (k `(i32.store16 ,(parse-mem-arg))))
  305. (#x3c (k `(i64.store8 ,(parse-mem-arg))))
  306. (#x3d (k `(i64.store16 ,(parse-mem-arg))))
  307. (#x3e (k `(i64.store32 ,(parse-mem-arg))))
  308. (#x3f (k `(memory.size ,(parse-idx))))
  309. (#x40 (k `(memory.grow ,(parse-idx))))
  310. (#x41 (k `(i32.const ,(get-sleb port))))
  311. (#x42 (k `(i64.const ,(get-sleb port))))
  312. (#x43 (k `(f32.const
  313. ,(let ((bytes (get-bytes port 4)))
  314. (bytevector-ieee-single-ref bytes 0
  315. (endianness little))))))
  316. (#x44 (k `(f64.const
  317. ,(let ((bytes (get-bytes port 8)))
  318. (bytevector-ieee-double-ref bytes 0
  319. (endianness little))))))
  320. (#x45 (k '(i32.eqz)))
  321. (#x46 (k '(i32.eq)))
  322. (#x47 (k '(i32.ne)))
  323. (#x48 (k '(i32.lt_s)))
  324. (#x49 (k '(i32.lt_u)))
  325. (#x4a (k '(i32.gt_s)))
  326. (#x4b (k '(i32.gt_u)))
  327. (#x4c (k '(i32.le_s)))
  328. (#x4d (k '(i32.le_u)))
  329. (#x4e (k '(i32.ge_s)))
  330. (#x4f (k '(i32.ge_u)))
  331. (#x50 (k '(i64.eqz)))
  332. (#x51 (k '(i64.eq)))
  333. (#x52 (k '(i64.ne)))
  334. (#x53 (k '(i64.lt_s)))
  335. (#x54 (k '(i64.lt_u)))
  336. (#x55 (k '(i64.gt_s)))
  337. (#x56 (k '(i64.gt_u)))
  338. (#x57 (k '(i64.le_s)))
  339. (#x58 (k '(i64.le_u)))
  340. (#x59 (k '(i64.ge_s)))
  341. (#x5a (k '(i64.ge_u)))
  342. (#x5b (k '(f32.eq)))
  343. (#x5c (k '(f32.ne)))
  344. (#x5d (k '(f32.lt)))
  345. (#x5e (k '(f32.gt)))
  346. (#x5f (k '(f32.le)))
  347. (#x60 (k '(f32.ge)))
  348. (#x61 (k '(f64.eq)))
  349. (#x62 (k '(f64.ne)))
  350. (#x63 (k '(f64.lt)))
  351. (#x64 (k '(f64.gt)))
  352. (#x65 (k '(f64.le)))
  353. (#x66 (k '(f64.ge)))
  354. (#x67 (k '(i32.clz)))
  355. (#x68 (k '(i32.ctz)))
  356. (#x69 (k '(i32.popcnt)))
  357. (#x6a (k '(i32.add)))
  358. (#x6b (k '(i32.sub)))
  359. (#x6c (k '(i32.mul)))
  360. (#x6d (k '(i32.div_s)))
  361. (#x6e (k '(i32.div_u)))
  362. (#x6f (k '(i32.rem_s)))
  363. (#x70 (k '(i32.rem_u)))
  364. (#x71 (k '(i32.and)))
  365. (#x72 (k '(i32.or)))
  366. (#x73 (k '(i32.xor)))
  367. (#x74 (k '(i32.shl)))
  368. (#x75 (k '(i32.shr_s)))
  369. (#x76 (k '(i32.shr_u)))
  370. (#x77 (k '(i32.rotl)))
  371. (#x78 (k '(i32.rotr)))
  372. (#x79 (k '(i64.clz)))
  373. (#x7a (k '(i64.ctz)))
  374. (#x7b (k '(i64.popcnt)))
  375. (#x7c (k '(i64.add)))
  376. (#x7d (k '(i64.sub)))
  377. (#x7e (k '(i64.mul)))
  378. (#x7f (k '(i64.div_s)))
  379. (#x80 (k '(i64.div_u)))
  380. (#x81 (k '(i64.rem_s)))
  381. (#x82 (k '(i64.rem_u)))
  382. (#x83 (k '(i64.and)))
  383. (#x84 (k '(i64.or)))
  384. (#x85 (k '(i64.xor)))
  385. (#x86 (k '(i64.shl)))
  386. (#x87 (k '(i64.shr_s)))
  387. (#x88 (k '(i64.shr_u)))
  388. (#x89 (k '(i64.rotl)))
  389. (#x8a (k '(i64.rotr)))
  390. (#x8b (k '(f32.abs)))
  391. (#x8c (k '(f32.neg)))
  392. (#x8d (k '(f32.ceil)))
  393. (#x8e (k '(f32.floor)))
  394. (#x8f (k '(f32.trunc)))
  395. (#x90 (k '(f32.nearest)))
  396. (#x91 (k '(f32.sqrt)))
  397. (#x92 (k '(f32.add)))
  398. (#x93 (k '(f32.sub)))
  399. (#x94 (k '(f32.mul)))
  400. (#x95 (k '(f32.div)))
  401. (#x96 (k '(f32.min)))
  402. (#x97 (k '(f32.max)))
  403. (#x98 (k '(f32.copysign)))
  404. (#x99 (k '(f64.abs)))
  405. (#x9a (k '(f64.neg)))
  406. (#x9b (k '(f64.ceil)))
  407. (#x9c (k '(f64.floor)))
  408. (#x9d (k '(f64.trunc)))
  409. (#x9e (k '(f64.nearest)))
  410. (#x9f (k '(f64.sqrt)))
  411. (#xa0 (k '(f64.add)))
  412. (#xa1 (k '(f64.sub)))
  413. (#xa2 (k '(f64.mul)))
  414. (#xa3 (k '(f64.div)))
  415. (#xa4 (k '(f64.min)))
  416. (#xa5 (k '(f64.max)))
  417. (#xa6 (k '(f64.copysign)))
  418. (#xa7 (k '(i32.wrap_i64)))
  419. (#xa8 (k '(i32.trunc_f32_s)))
  420. (#xa9 (k '(i32.trunc_f32_u)))
  421. (#xaa (k '(i32.trunc_f64_s)))
  422. (#xab (k '(i32.trunc_f64_u)))
  423. (#xac (k '(i64.extend_i32_s)))
  424. (#xad (k '(i64.extend_i32_u)))
  425. (#xae (k '(i64.trunc_f32_s)))
  426. (#xaf (k '(i64.trunc_f32_u)))
  427. (#xb0 (k '(i64.trunc_f64_s)))
  428. (#xb1 (k '(i64.trunc_f64_u)))
  429. (#xb2 (k '(f32.convert_i32_s)))
  430. (#xb3 (k '(f32.convert_i32_u)))
  431. (#xb4 (k '(f32.convert_i64_s)))
  432. (#xb5 (k '(f32.convert_i64_u)))
  433. (#xb6 (k '(f32.demote_f64)))
  434. (#xb7 (k '(f64.convert_i32_s)))
  435. (#xb8 (k '(f64.convert_i32_u)))
  436. (#xb9 (k '(f64.convert_i64_s)))
  437. (#xba (k '(f64.convert_i64_u)))
  438. (#xbb (k '(f64.promote_f32)))
  439. (#xbc (k '(i32.reinterpret_f32)))
  440. (#xbd (k '(i64.reinterpret_f64)))
  441. (#xbe (k '(f32.reinterpret_i32)))
  442. (#xbf (k '(f64.reinterpret_i64)))
  443. (#xc0 (k '(i32.extend8_s)))
  444. (#xc1 (k '(i32.extend16_s)))
  445. (#xc2 (k '(i64.extend8_s)))
  446. (#xc3 (k '(i64.extend16_s)))
  447. (#xc4 (k '(i64.extend32_s)))
  448. (#xd0 (k `(ref.null ,(parse-heap-type port))))
  449. (#xd1 (k `(ref.is_null)))
  450. (#xd2 (k `(ref.func ,(parse-idx))))
  451. (#xd3 (k `(ref.eq)))
  452. (#xd4 (k `(ref.as_non_null)))
  453. (#xfb
  454. (match (get-uleb port)
  455. (0 (k `(struct.new ,(parse-idx))))
  456. (1 (k `(struct.new_default ,(parse-idx))))
  457. (2 (let* ((type (parse-idx))
  458. (field (parse-idx)))
  459. (k `(struct.get ,type ,field))))
  460. (3 (let* ((type (parse-idx))
  461. (field (parse-idx)))
  462. (k `(struct.get_s ,type ,field))))
  463. (4 (let* ((type (parse-idx))
  464. (field (parse-idx)))
  465. (k `(struct.get_u ,type ,field))))
  466. (5 (let* ((type (parse-idx))
  467. (field (parse-idx)))
  468. (k `(struct.set ,type ,field))))
  469. (6 (k `(array.new ,(parse-idx))))
  470. (7 (k `(array.new_default ,(parse-idx))))
  471. (8 (let* ((type (parse-idx))
  472. (len (get-uleb port)))
  473. (k `(array.new_fixed ,type ,len))))
  474. (9 (let* ((type (parse-idx))
  475. (data (parse-idx)))
  476. (k `(array.new_data ,type ,data))))
  477. (10 (let* ((type (parse-idx))
  478. (elem (parse-idx)))
  479. (k `(array.new_elem ,type ,elem))))
  480. (11 (k `(array.get ,(parse-idx))))
  481. (12 (k `(array.get_s ,(parse-idx))))
  482. (13 (k `(array.get_u ,(parse-idx))))
  483. (14 (k `(array.set ,(parse-idx))))
  484. (15 (k `(array.len)))
  485. (16 (k `(array.fill ,(parse-idx))))
  486. (17 (let* ((dst (parse-idx))
  487. (src (parse-idx)))
  488. (k `(array.copy ,dst ,src))))
  489. (18 (let* ((dst (parse-idx))
  490. (src (parse-idx)))
  491. (k `(array.init_data ,dst ,src))))
  492. (19 (let* ((dst (parse-idx))
  493. (src (parse-idx)))
  494. (k `(array.init_elem ,dst ,src))))
  495. (20 (k `(ref.test ,(make-ref-type #f (parse-heap-type port)))))
  496. (21 (k `(ref.test ,(make-ref-type #t (parse-heap-type port)))))
  497. (22 (k `(ref.cast ,(make-ref-type #f (parse-heap-type port)))))
  498. (23 (k `(ref.cast ,(make-ref-type #t (parse-heap-type port)))))
  499. (24 (let* ((flags (get-u8 port))
  500. (rt1 (make-ref-type (logtest 1 flags)
  501. (parse-heap-type port)))
  502. (rt2 (make-ref-type (logtest 2 flags)
  503. (parse-heap-type port))))
  504. `(br_on_cast ,rt1 ,rt2)))
  505. (25 (let* ((flags (get-u8 port))
  506. (rt1 (make-ref-type (logtest 1 flags)
  507. (parse-heap-type port)))
  508. (rt2 (make-ref-type (logtest 2 flags)
  509. (parse-heap-type port))))
  510. `(br_on_cast_fail ,rt1 ,rt2)))
  511. (26 (k `(extern.internalize)))
  512. (27 (k `(extern.externalize)))
  513. (28 (k `(ref.i31)))
  514. (29 (k `(i31.get_s)))
  515. (30 (k `(i31.get_u)))
  516. (#x80 (k `(string.new_utf8 ,(parse-idx))))
  517. (#x81 (k `(string.new_wtf16 ,(parse-idx))))
  518. (#x82 (k `(string.const ,(parse-idx))))
  519. (#x83 (k `(string.measure_utf8)))
  520. (#x84 (k `(string.measure_wtf8)))
  521. (#x85 (k `(string.measure_wtf16)))
  522. (#x86 (k `(string.encode_utf8 ,(parse-idx))))
  523. (#x87 (k `(string.encode_wtf16 ,(parse-idx))))
  524. (#x88 (k `(string.concat)))
  525. (#x89 (k `(string.eq)))
  526. (#x8a (k `(string.is_usv_sequence)))
  527. (#x8b (k `(string.new_lossy_utf8 ,(parse-idx))))
  528. (#x8c (k `(string.new_wtf8 ,(parse-idx))))
  529. (#x8d (k `(string.encode_lossy_utf8 ,(parse-idx))))
  530. (#x8e (k `(string.encode_wtf8 ,(parse-idx))))
  531. (#x90 (k `(string.as_wtf8)))
  532. (#x91 (k `(stringview_wtf8.advance)))
  533. (#x92 (k `(stringview_wtf8.encode_utf8 ,(parse-idx))))
  534. (#x93 (k `(stringview_wtf8.slice)))
  535. (#x94 (k `(stringview_wtf8.encode_lossy_utf8 ,(parse-idx))))
  536. (#x95 (k `(stringview_wtf8.encode_wtf8 ,(parse-idx))))
  537. (#x98 (k `(string.as_wtf16)))
  538. (#x99 (k `(stringview_wtf16.length)))
  539. (#x9a (k `(stringview_wtf16.get_codeunit)))
  540. (#x9b (k `(stringview_wtf16.encode ,(parse-idx))))
  541. (#x9c (k `(stringview_wtf16.slice)))
  542. (#xa0 (k `(string.as_iter)))
  543. (#xa1 (k `(stringview_iter.next)))
  544. (#xa2 (k `(stringview_iter.advance)))
  545. (#xa3 (k `(stringview_iter.rewind)))
  546. (#xa4 (k `(stringview_iter.slice)))
  547. (#xa8 (k `(string.compare)))
  548. (#xa9 (k `(string.from_code_point)))
  549. (#xb0 (k `(string.new_utf8_array)))
  550. (#xb1 (k `(string.new_wtf16_array)))
  551. (#xb2 (k `(string.encode_utf8_array)))
  552. (#xb3 (k `(string.encode_wtf16_array)))
  553. (#xb4 (k `(string.new_lossy_utf8_array)))
  554. (#xb5 (k `(string.new_wtf8_array)))
  555. (#xb6 (k `(string.encode_lossy_utf8_array)))
  556. (#xb7 (k `(string.encode_wtf8_array)))
  557. (idx (error "unexpected GC opcode" idx))))
  558. (#xfc
  559. (match (get-uleb port)
  560. (#x00 (k `(i32.trunc_sat_f32_s)))
  561. (#x01 (k `(i32.trunc_sat_f32_u)))
  562. (#x02 (k `(i32.trunc_sat_f64_s)))
  563. (#x03 (k `(i32.trunc_sat_f64_u)))
  564. (#x04 (k `(i64.trunc_sat_f32_s)))
  565. (#x05 (k `(i64.trunc_sat_f32_u)))
  566. (#x06 (k `(i64.trunc_sat_f64_s)))
  567. (#x07 (k `(i64.trunc_sat_f64_u)))
  568. (#x08 (let* ((data (parse-idx))
  569. (mem (parse-idx)))
  570. (k `(memory.init ,data ,mem))))
  571. (#x09 (k `(data.drop ,(parse-idx))))
  572. (#x0a (let* ((dst (parse-idx))
  573. (src (parse-idx)))
  574. (k `(memory.copy ,dst ,src))))
  575. (#x0b (k `(memory.fill ,(parse-idx))))
  576. (#x0c (let* ((elem (parse-idx))
  577. (table (parse-idx)))
  578. (k `(table.init ,elem ,table))))
  579. (#x0d (k `(elem.drop ,(parse-idx))))
  580. (#x0e (let* ((dst (parse-idx))
  581. (src (parse-idx)))
  582. (k `(table.copy ,dst ,src))))
  583. (#x0f (k `(table.grow ,(get-uleb port))))
  584. (#x10 (k `(table.size ,(get-uleb port))))
  585. (#x11 (k `(table.fill ,(get-uleb port))))
  586. (idx (error "unexpected misc instruction" idx))))
  587. (#xfd
  588. (match (get-uleb port)
  589. (#x00 (k `(v128.load ,(parse-mem-arg))))
  590. (#x01 (k `(v128.load8x8_s ,(parse-mem-arg))))
  591. (#x02 (k `(v128.load8x8_u ,(parse-mem-arg))))
  592. (#x03 (k `(v128.load16x4_s ,(parse-mem-arg))))
  593. (#x04 (k `(v128.load16x4_u ,(parse-mem-arg))))
  594. (#x05 (k `(v128.load32x2_s ,(parse-mem-arg))))
  595. (#x06 (k `(v128.load32x2_u ,(parse-mem-arg))))
  596. (#x07 (k `(v128.load8_splat ,(parse-mem-arg))))
  597. (#x08 (k `(v128.load16_splat ,(parse-mem-arg))))
  598. (#x09 (k `(v128.load32_splat ,(parse-mem-arg))))
  599. (#x0a (k `(v128.load64_splat ,(parse-mem-arg))))
  600. (#x0b (k `(v128.store ,(parse-mem-arg))))
  601. (#x0c (k `(v128.const ,(get-bytes port 16))))
  602. (#x0d (k `(i8x16.shuffle ,(get-bytes port 16))))
  603. (#x0e (k `(i8x16.swizzle)))
  604. (#x0f (k `(i8x16.splat)))
  605. (#x10 (k `(i16x8.splat)))
  606. (#x11 (k `(i32x4.splat)))
  607. (#x12 (k `(i64x2.splat)))
  608. (#x13 (k `(f32x4.splat)))
  609. (#x14 (k `(f64x2.splat)))
  610. (#x15 (k `(i8x16.extract_lane_s ,(get-u8 port))))
  611. (#x16 (k `(i8x16.extract_lane_u ,(get-u8 port))))
  612. (#x17 (k `(i8x16.replace_lane ,(get-u8 port))))
  613. (#x18 (k `(i16x8.extract_lane_s ,(get-u8 port))))
  614. (#x19 (k `(i16x8.extract_lane_u ,(get-u8 port))))
  615. (#x1a (k `(i16x8.replace_lane ,(get-u8 port))))
  616. (#x1b (k `(i32x4.extract_lane ,(get-u8 port))))
  617. (#x1c (k `(i32x4.replace_lane ,(get-u8 port))))
  618. (#x1d (k `(i64x2.extract_lane ,(get-u8 port))))
  619. (#x1e (k `(i64x2.replace_lane ,(get-u8 port))))
  620. (#x1f (k `(f32x4.extract_lane ,(get-u8 port))))
  621. (#x20 (k `(f32x4.replace_lane ,(get-u8 port))))
  622. (#x21 (k `(f64x2.extract_lane ,(get-u8 port))))
  623. (#x22 (k `(f64x2.replace_lane ,(get-u8 port))))
  624. (#x23 (k `(i8x16.eq)))
  625. (#x24 (k `(i8x16.ne)))
  626. (#x25 (k `(i8x16.lt_s)))
  627. (#x26 (k `(i8x16.lt_u)))
  628. (#x27 (k `(i8x16.gt_s)))
  629. (#x28 (k `(i8x16.gt_u)))
  630. (#x29 (k `(i8x16.le_s)))
  631. (#x2a (k `(i8x16.le_u)))
  632. (#x2b (k `(i8x16.ge_s)))
  633. (#x2c (k `(i8x16.ge_u)))
  634. (#x2d (k `(i16x8.eq)))
  635. (#x2e (k `(i16x8.ne)))
  636. (#x2f (k `(i16x8.lt_s)))
  637. (#x30 (k `(i16x8.lt_u)))
  638. (#x31 (k `(i16x8.gt_s)))
  639. (#x32 (k `(i16x8.gt_u)))
  640. (#x33 (k `(i16x8.le_s)))
  641. (#x34 (k `(i16x8.le_u)))
  642. (#x35 (k `(i16x8.ge_s)))
  643. (#x36 (k `(i16x8.ge_u)))
  644. (#x37 (k `(i32x4.eq)))
  645. (#x38 (k `(i32x4.ne)))
  646. (#x39 (k `(i32x4.lt_s)))
  647. (#x3a (k `(i32x4.lt_u)))
  648. (#x3b (k `(i32x4.gt_s)))
  649. (#x3c (k `(i32x4.gt_u)))
  650. (#x3d (k `(i32x4.le_s)))
  651. (#x3e (k `(i32x4.le_u)))
  652. (#x3f (k `(i32x4.ge_s)))
  653. (#x40 (k `(i32x4.ge_u)))
  654. (#x41 (k `(f32x4.eq)))
  655. (#x42 (k `(f32x4.ne)))
  656. (#x43 (k `(f32x4.lt)))
  657. (#x44 (k `(f32x4.gt)))
  658. (#x45 (k `(f32x4.le)))
  659. (#x46 (k `(f32x4.ge)))
  660. (#x47 (k `(f64x2.eq)))
  661. (#x48 (k `(f64x2.ne)))
  662. (#x49 (k `(f64x2.lt)))
  663. (#x4a (k `(f64x2.gt)))
  664. (#x4b (k `(f64x2.le)))
  665. (#x4c (k `(f64x2.ge)))
  666. (#x4d (k `(v128.not)))
  667. (#x4e (k `(v128.and)))
  668. (#x4f (k `(v128.andnot)))
  669. (#x50 (k `(v128.or)))
  670. (#x51 (k `(v128.xor)))
  671. (#x52 (k `(v128.bitselect)))
  672. (#x53 (k `(v128.any_true)))
  673. (#x54 (let* ((mem-arg (parse-mem-arg))
  674. (lane (get-u8 port)))
  675. (k `(v128.load8_lane ,mem-arg ,lane))))
  676. (#x55 (let* ((mem-arg (parse-mem-arg))
  677. (lane (get-u8 port)))
  678. (k `(v128.load16_lane ,mem-arg ,lane))))
  679. (#x56 (let* ((mem-arg (parse-mem-arg))
  680. (lane (get-u8 port)))
  681. (k `(v128.load32_lane ,mem-arg ,lane))))
  682. (#x57 (let* ((mem-arg (parse-mem-arg))
  683. (lane (get-u8 port)))
  684. (k `(v128.load64_lane ,mem-arg ,lane))))
  685. (#x58 (let* ((mem-arg (parse-mem-arg))
  686. (lane (get-u8 port)))
  687. (k `(v128.store8_lane ,mem-arg ,lane))))
  688. (#x59 (let* ((mem-arg (parse-mem-arg))
  689. (lane (get-u8 port)))
  690. (k `(v128.store16_lane ,mem-arg ,lane))))
  691. (#x5a (let* ((mem-arg (parse-mem-arg))
  692. (lane (get-u8 port)))
  693. (k `(v128.store32_lane ,mem-arg ,lane))))
  694. (#x5b (let* ((mem-arg (parse-mem-arg))
  695. (lane (get-u8 port)))
  696. (k `(v128.store64_lane ,mem-arg ,lane))))
  697. (#x5c (k `(v128.load32_zero ,(parse-mem-arg))))
  698. (#x5d (k `(v128.load64_zero ,(parse-mem-arg))))
  699. (#x5e (k `(f32x4.demote_f64x2_zero)))
  700. (#x5f (k `(f64x2.promote_low_f32x4)))
  701. (#x60 (k `(i8x16.abs)))
  702. (#x61 (k `(i8x16.neg)))
  703. (#x62 (k `(i8x16.popcnt)))
  704. (#x63 (k `(i8x16.all_true)))
  705. (#x64 (k `(i8x16.bitmask)))
  706. (#x65 (k `(i8x16.narrow_i16x8_s)))
  707. (#x66 (k `(i8x16.narrow_i16x8_u)))
  708. (#x67 (k `(f32x4.ceil)))
  709. (#x68 (k `(f32x4.floor)))
  710. (#x69 (k `(f32x4.trunc)))
  711. (#x6a (k `(f32x4.nearest)))
  712. (#x6b (k `(i8x16.shl)))
  713. (#x6c (k `(i8x16.shr_s)))
  714. (#x6d (k `(i8x16.shr_u)))
  715. (#x6e (k `(i8x16.add)))
  716. (#x6f (k `(i8x16.add_sat_s)))
  717. (#x70 (k `(i8x16.add_sat_u)))
  718. (#x71 (k `(i8x16.sub)))
  719. (#x72 (k `(i8x16.sub_sat_s)))
  720. (#x73 (k `(i8x16.sub_sat_u)))
  721. (#x74 (k `(f64x2.ceil)))
  722. (#x75 (k `(f64x2.floor)))
  723. (#x76 (k `(i8x16.min_s)))
  724. (#x77 (k `(i8x16.min_u)))
  725. (#x78 (k `(i8x16.max_s)))
  726. (#x79 (k `(i8x16.max_u)))
  727. (#x7a (k `(f64x2.trunc)))
  728. (#x7b (k `(i8x16.avgr_u)))
  729. (#x7c (k `(i16x8.extadd_pairwise_i8x16_s)))
  730. (#x7d (k `(i16x8.extadd_pairwise_i8x16_u)))
  731. (#x7e (k `(i32x4.extadd_pairwise_i16x8_s)))
  732. (#x7f (k `(i32x4.extadd_pairwise_i16x8_u)))
  733. (#x80 (k `(i16x8.abs)))
  734. (#x81 (k `(i16x8.neg)))
  735. (#x82 (k `(i16x8.q15mulr_sat_s)))
  736. (#x83 (k `(i16x8.all_true)))
  737. (#x84 (k `(i16x8.bitmask)))
  738. (#x85 (k `(i16x8.narrow_i32x4_s)))
  739. (#x86 (k `(i16x8.narrow_i32x4_u)))
  740. (#x87 (k `(i16x8.extend_low_i8x16_s)))
  741. (#x88 (k `(i16x8.extend_high_i8x16_s)))
  742. (#x89 (k `(i16x8.extend_low_i8x16_u)))
  743. (#x8a (k `(i16x8.extend_high_i8x16_u)))
  744. (#x8b (k `(i16x8.shl)))
  745. (#x8c (k `(i16x8.shr_s)))
  746. (#x8d (k `(i16x8.shr_u)))
  747. (#x8e (k `(i16x8.add)))
  748. (#x8f (k `(i16x8.add_sat_s)))
  749. (#x90 (k `(i16x8.add_sat_u)))
  750. (#x91 (k `(i16x8.sub)))
  751. (#x92 (k `(i16x8.sub_sat_s)))
  752. (#x93 (k `(i16x8.sub_sat_u)))
  753. (#x94 (k `(f64x2.nearest)))
  754. (#x95 (k `(i16x8.mul)))
  755. (#x96 (k `(i16x8.min_s)))
  756. (#x97 (k `(i16x8.min_u)))
  757. (#x98 (k `(i16x8.max_s)))
  758. (#x99 (k `(i16x8.max_u)))
  759. (#x9b (k `(i16x8.avgr_u)))
  760. (#x9c (k `(i16x8.extmul_low_i8x16_s)))
  761. (#x9d (k `(i16x8.extmul_high_i8x16_s)))
  762. (#x9e (k `(i16x8.extmul_low_i8x16_u)))
  763. (#x9f (k `(i16x8.extmul_high_i8x16_u)))
  764. (#xa0 (k `(i32x4.abs)))
  765. (#xa1 (k `(i32x4.neg)))
  766. (#xa3 (k `(i32x4.all_true)))
  767. (#xa4 (k `(i32x4.bitmask)))
  768. (#xa7 (k `(i32x4.extend_low_i16x8_s)))
  769. (#xa8 (k `(i32x4.extend_high_i16x8_s)))
  770. (#xa9 (k `(i32x4.extend_low_i16x8_u)))
  771. (#xaa (k `(i32x4.extend_high_i16x8_u)))
  772. (#xab (k `(i32x4.shl)))
  773. (#xac (k `(i32x4.shr_s)))
  774. (#xad (k `(i32x4.shr_u)))
  775. (#xae (k `(i32x4.add)))
  776. (#xb1 (k `(i32x4.sub)))
  777. (#xb5 (k `(i32x4.mul)))
  778. (#xb6 (k `(i32x4.min_s)))
  779. (#xb7 (k `(i32x4.min_u)))
  780. (#xb8 (k `(i32x4.max_s)))
  781. (#xb9 (k `(i32x4.max_u)))
  782. (#xba (k `(i32x4.dot_i16x8_s)))
  783. (#xbc (k `(i32x4.extmul_low_i16x8_s)))
  784. (#xbd (k `(i32x4.extmul_high_i16x8_s)))
  785. (#xbe (k `(i32x4.extmul_low_i16x8_u)))
  786. (#xbf (k `(i32x4.extmul_high_i16x8_u)))
  787. (#xc0 (k `(i64x2.abs)))
  788. (#xc1 (k `(i64x2.neg)))
  789. (#xc3 (k `(i64x2.all_true)))
  790. (#xc4 (k `(i64x2.bitmask)))
  791. (#xc7 (k `(i64x2.extend_low_i32x4_s)))
  792. (#xc8 (k `(i64x2.extend_high_i32x4_s)))
  793. (#xc9 (k `(i64x2.extend_low_i32x4_u)))
  794. (#xca (k `(i64x2.extend_high_i32x4_u)))
  795. (#xcb (k `(i64x2.shl)))
  796. (#xcc (k `(i64x2.shr_s)))
  797. (#xcd (k `(i64x2.shr_u)))
  798. (#xce (k `(i64x2.add)))
  799. (#xd1 (k `(i64x2.sub)))
  800. (#xd5 (k `(i64x2.mul)))
  801. (#xd6 (k `(i64x2.eq)))
  802. (#xd7 (k `(i64x2.ne)))
  803. (#xd8 (k `(i64x2.lt_s)))
  804. (#xd9 (k `(i64x2.gt_s)))
  805. (#xda (k `(i64x2.le_s)))
  806. (#xdb (k `(i64x2.ge_s)))
  807. (#xdc (k `(i64x2.extmul_low_i32x4_s)))
  808. (#xdd (k `(i64x2.extmul_high_i32x4_s)))
  809. (#xde (k `(i64x2.extmul_low_i32x4_u)))
  810. (#xdf (k `(i64x2.extmul_high_i32x4_u)))
  811. (#xe0 (k `(f32x4.abs)))
  812. (#xe1 (k `(f32x4.neg)))
  813. (#xe3 (k `(f32x4.sqrt)))
  814. (#xe4 (k `(f32x4.add)))
  815. (#xe5 (k `(f32x4.sub)))
  816. (#xe6 (k `(f32x4.mul)))
  817. (#xe7 (k `(f32x4.div)))
  818. (#xe8 (k `(f32x4.min)))
  819. (#xe9 (k `(f32x4.max)))
  820. (#xea (k `(f32x4.pmin)))
  821. (#xeb (k `(f32x4.pmax)))
  822. (#xec (k `(f64x2.abs)))
  823. (#xed (k `(f64x2.neg)))
  824. (#xef (k `(f64x2.sqrt)))
  825. (#xf0 (k `(f64x2.add)))
  826. (#xf1 (k `(f64x2.sub)))
  827. (#xf2 (k `(f64x2.mul)))
  828. (#xf3 (k `(f64x2.div)))
  829. (#xf4 (k `(f64x2.min)))
  830. (#xf5 (k `(f64x2.max)))
  831. (#xf6 (k `(f64x2.pmin)))
  832. (#xf7 (k `(f64x2.pmax)))
  833. (#xf8 (k `(i32x4.trunc_sat_f32x4_s)))
  834. (#xf9 (k `(i32x4.trunc_sat_f32x4_u)))
  835. (#xfa (k `(f32x4.convert_i32x4_s)))
  836. (#xfb (k `(f32x4.convert_i32x4_u)))
  837. (#xfc (k `(i32x4.trunc_sat_f64x2_s_zero)))
  838. (#xfd (k `(i32x4.trunc_sat_f64x2_u_zero)))
  839. (#xfe (k `(f64x2.convert_low_i32x4_s)))
  840. (#xff (k `(f64x2.convert_low_i32x4_u)))
  841. (#x100 (k `(i8x16.relaxed_swizzle)))
  842. (#x101 (k `(i32x4.relaxed_trunc_f32x4_s)))
  843. (#x102 (k `(i32x4.relaxed_trunc_f32x4_u)))
  844. (#x103 (k `(i32x4.relaxed_trunc_f64x2_s_zero)))
  845. (#x104 (k `(i32x4.relaxed_trunc_f64x2_u_zero)))
  846. (#x105 (k `(f32x4.qfma)))
  847. (#x106 (k `(f32x4.qfms)))
  848. (#x107 (k `(f64x2.qfma)))
  849. (#x108 (k `(f64x2.qfms)))
  850. (#x109 (k `(i8x16.relaxed_laneselect)))
  851. (#x10a (k `(i16x8.relaxed_laneselect)))
  852. (#x10b (k `(i32x4.relaxed_laneselect)))
  853. (#x10c (k `(i64x2.relaxed_laneselect)))
  854. (#x10d (k `(f32x4.relaxed_min)))
  855. (#x10e (k `(f32x4.relaxed_max)))
  856. (#x10f (k `(f64x2.relaxed_min)))
  857. (#x110 (k `(f64x2.relaxed_max)))
  858. (#x111 (k `(i16x8.relaxed_q15mulr_s)))
  859. (#x112 (k `(i16x8.dot_i8x16_i7x16_s)))
  860. (#x113 (k `(i32x4.dot_i8x16_i7x16_add_s)))
  861. (idx (error "unexpected simd instruction" idx))))
  862. (#xfe
  863. (match (get-uleb port)
  864. (#x00 (k `(memory.atomic.notify ,(parse-mem-arg))))
  865. (#x01 (k `(memory.atomic.wait32 ,(parse-mem-arg))))
  866. (#x02 (k `(memory.atomic.wait64 ,(parse-mem-arg))))
  867. (#x03 (k `(atomic.fence))) ;; no mem arg
  868. (#x10 (k `(i32.atomic.load ,(parse-mem-arg))))
  869. (#x11 (k `(i64.atomic.load ,(parse-mem-arg))))
  870. (#x12 (k `(i32.atomic.load8_u ,(parse-mem-arg))))
  871. (#x13 (k `(i32.atomic.load16_u ,(parse-mem-arg))))
  872. (#x14 (k `(i64.atomic.load8_u ,(parse-mem-arg))))
  873. (#x15 (k `(i64.atomic.load16_u ,(parse-mem-arg))))
  874. (#x16 (k `(i64.atomic.load32_u ,(parse-mem-arg))))
  875. (#x17 (k `(i32.atomic.store ,(parse-mem-arg))))
  876. (#x18 (k `(i64.atomic.store ,(parse-mem-arg))))
  877. (#x19 (k `(i32.atomic.store8 ,(parse-mem-arg))))
  878. (#x1a (k `(i32.atomic.store16 ,(parse-mem-arg))))
  879. (#x1b (k `(i64.atomic.store8 ,(parse-mem-arg))))
  880. (#x1c (k `(i64.atomic.store16 ,(parse-mem-arg))))
  881. (#x1d (k `(i64.atomic.store32 ,(parse-mem-arg))))
  882. (#x1e (k `(i32.atomic.rmw.add ,(parse-mem-arg))))
  883. (#x1f (k `(i64.atomic.rmw.add ,(parse-mem-arg))))
  884. (#x20 (k `(i32.atomic.rmw8.add_u ,(parse-mem-arg))))
  885. (#x21 (k `(i32.atomic.rmw16.add_u ,(parse-mem-arg))))
  886. (#x22 (k `(i64.atomic.rmw8.add_u ,(parse-mem-arg))))
  887. (#x23 (k `(i64.atomic.rmw16.add_u ,(parse-mem-arg))))
  888. (#x24 (k `(i64.atomic.rmw32.add_u ,(parse-mem-arg))))
  889. (#x25 (k `(i32.atomic.rmw.sub ,(parse-mem-arg))))
  890. (#x26 (k `(i64.atomic.rmw.sub ,(parse-mem-arg))))
  891. (#x27 (k `(i32.atomic.rmw8.sub_u ,(parse-mem-arg))))
  892. (#x28 (k `(i32.atomic.rmw16.sub_u ,(parse-mem-arg))))
  893. (#x29 (k `(i64.atomic.rmw8.sub_u ,(parse-mem-arg))))
  894. (#x2a (k `(i64.atomic.rmw16.sub_u ,(parse-mem-arg))))
  895. (#x2b (k `(i64.atomic.rmw32.sub_u ,(parse-mem-arg))))
  896. (#x2c (k `(i32.atomic.rmw.and ,(parse-mem-arg))))
  897. (#x2d (k `(i64.atomic.rmw.and ,(parse-mem-arg))))
  898. (#x2e (k `(i32.atomic.rmw8.and_u ,(parse-mem-arg))))
  899. (#x2f (k `(i32.atomic.rmw16.and_u ,(parse-mem-arg))))
  900. (#x30 (k `(i64.atomic.rmw8.and_u ,(parse-mem-arg))))
  901. (#x31 (k `(i64.atomic.rmw16.and_u ,(parse-mem-arg))))
  902. (#x32 (k `(i64.atomic.rmw32.and_u ,(parse-mem-arg))))
  903. (#x33 (k `(i32.atomic.rmw.or ,(parse-mem-arg))))
  904. (#x34 (k `(i64.atomic.rmw.or ,(parse-mem-arg))))
  905. (#x35 (k `(i32.atomic.rmw8.or_u ,(parse-mem-arg))))
  906. (#x36 (k `(i32.atomic.rmw16.or_u ,(parse-mem-arg))))
  907. (#x37 (k `(i64.atomic.rmw8.or_u ,(parse-mem-arg))))
  908. (#x38 (k `(i64.atomic.rmw16.or_u ,(parse-mem-arg))))
  909. (#x39 (k `(i64.atomic.rmw32.or_u ,(parse-mem-arg))))
  910. (#x3a (k `(i32.atomic.rmw.xor ,(parse-mem-arg))))
  911. (#x3b (k `(i64.atomic.rmw.xor ,(parse-mem-arg))))
  912. (#x3c (k `(i32.atomic.rmw8.xor_u ,(parse-mem-arg))))
  913. (#x3d (k `(i32.atomic.rmw16.xor_u ,(parse-mem-arg))))
  914. (#x3e (k `(i64.atomic.rmw8.xor_u ,(parse-mem-arg))))
  915. (#x3f (k `(i64.atomic.rmw16.xor_u ,(parse-mem-arg))))
  916. (#x40 (k `(i64.atomic.rmw32.xor_u ,(parse-mem-arg))))
  917. (#x41 (k `(i32.atomic.rmw.xchg ,(parse-mem-arg))))
  918. (#x42 (k `(i64.atomic.rmw.xchg ,(parse-mem-arg))))
  919. (#x43 (k `(i32.atomic.rmw8.xchg_u ,(parse-mem-arg))))
  920. (#x44 (k `(i32.atomic.rmw16.xchg_u ,(parse-mem-arg))))
  921. (#x45 (k `(i64.atomic.rmw8.xchg_u ,(parse-mem-arg))))
  922. (#x46 (k `(i64.atomic.rmw16.xchg_u ,(parse-mem-arg))))
  923. (#x47 (k `(i64.atomic.rmw32.xchg_u ,(parse-mem-arg))))
  924. (#x48 (k `(i32.atomic.rmw.cmpxchg ,(parse-mem-arg))))
  925. (#x49 (k `(i64.atomic.rmw.cmpxchg ,(parse-mem-arg))))
  926. (#x4a (k `(i32.atomic.rmw8.cmpxchg_u ,(parse-mem-arg))))
  927. (#x4b (k `(i32.atomic.rmw16.cmpxchg_u ,(parse-mem-arg))))
  928. (#x4c (k `(i64.atomic.rmw8.cmpxchg_u ,(parse-mem-arg))))
  929. (#x4d (k `(i64.atomic.rmw16.cmpxchg_u ,(parse-mem-arg))))
  930. (#x4e (k `(i64.atomic.rmw32.cmpxchg_u ,(parse-mem-arg))))
  931. (idx (error "unexpected atomic instruction" idx))))
  932. (byte (error "unexpected opcode" byte)))))
  933. (define (parse-body)
  934. (let-values (((body end-tok) (parse-body*)))
  935. (match end-tok
  936. ('end body)
  937. (_ (error "unexpected token" end-tok)))))
  938. (parse-body))
  939. (define (parse-tables port)
  940. (define (parse-table port)
  941. (cond
  942. ((match-u8 port #x40)
  943. (expect-u8 port #x00)
  944. (let* ((type (parse-table-type port))
  945. (init (parse-expr port)))
  946. (make-table #f type init)))
  947. (else
  948. (make-table #f (parse-table-type port) #f))))
  949. (parse-vec port parse-table))
  950. (define (parse-memories port)
  951. (define (parse-memory port)
  952. (make-memory #f (parse-mem-type port)))
  953. (parse-vec port parse-memory))
  954. (define (parse-tag port)
  955. (make-tag #f (parse-tag-type port)))
  956. (define (parse-tags port)
  957. (parse-vec port parse-tag))
  958. (define (parse-strings port)
  959. (expect-u8 port #x00)
  960. (parse-vec port get-name))
  961. (define (parse-globals port)
  962. (define (parse-global port)
  963. (let ((type (parse-global-type port)))
  964. (make-global #f type (parse-expr port))))
  965. (parse-vec port parse-global))
  966. (define (parse-exports port)
  967. (define (parse-export port)
  968. (let* ((name (get-name port))
  969. (type (match (get-u8 port)
  970. (#x00 'func)
  971. (#x01 'table)
  972. (#x02 'memory)
  973. (#x03 'global)
  974. (#x04 'tag)
  975. (byte (error "unexpected byte" byte)))))
  976. (make-export name type (get-uleb port))))
  977. (parse-vec port parse-export))
  978. (define (parse-start port)
  979. (get-uleb port))
  980. (define (parse-elems port)
  981. (define (parse-elem port)
  982. (define (ref-funcs indexes)
  983. (map (lambda (idx) `((ref.func ,idx))) indexes))
  984. (match (get-u8 port)
  985. (#x00 (let* ((offset (parse-expr port)))
  986. (make-elem #f 'active 0 'funcref offset
  987. (ref-funcs (parse-vec port get-uleb)))))
  988. (#x01 (expect-u8 port #x00)
  989. (make-elem #f 'passive #f 'funcref #f
  990. (ref-funcs (parse-vec port get-uleb))))
  991. (#x02 (let* ((table (get-uleb port))
  992. (offset (parse-expr port)))
  993. (expect-u8 port #x00)
  994. (make-elem #f 'active table 'funcref offset
  995. (ref-funcs (parse-vec port get-uleb)))))
  996. (#x03 (expect-u8 port #x00)
  997. (make-elem #f 'declarative #f 'funcref #f
  998. (ref-funcs (parse-vec port get-uleb))))
  999. (#x04 (let ((offset (parse-expr port)))
  1000. (make-elem #f 'active 0 'funcref offset
  1001. (parse-vec port parse-expr))))
  1002. (#x05 (let ((type (parse-ref-type port)))
  1003. (make-elem #f 'passive #f type #f
  1004. (parse-vec port parse-expr))))
  1005. (#x06 (let ((table (get-uleb port))
  1006. (offset (parse-expr port))
  1007. (type (parse-ref-type port)))
  1008. (make-elem #f 'active table type offset
  1009. (parse-vec port parse-expr))))
  1010. (#x07 (let ((type (parse-ref-type port)))
  1011. (make-elem #f 'declarative #f type #f
  1012. (parse-vec port parse-expr))))
  1013. (byte (error "unexpected byte" byte))))
  1014. (parse-vec port parse-elem))
  1015. (define (parse-func-bodies port)
  1016. (define (parse-code port)
  1017. (call-with-input-bytevector
  1018. (parse-vec/u8 port)
  1019. (lambda (port)
  1020. (define (parse-local port)
  1021. (let ((n (get-uleb port)))
  1022. (make-list n (make-local #f (parse-val-type port)))))
  1023. (let* ((locals (apply append (parse-vec port parse-local)))
  1024. (body (parse-expr port)))
  1025. (unless (eof-object? (lookahead-u8 port))
  1026. (error "unexpected trailing bytes in function"))
  1027. (make-func #f #f locals body)))))
  1028. (parse-vec port parse-code))
  1029. (define (parse-data-count port)
  1030. (get-uleb port))
  1031. (define (parse-data port)
  1032. (define (parse-segment port)
  1033. (match (get-u8 port)
  1034. (#x00 (let ((offset (parse-expr port)))
  1035. (make-data #f 'active 0 offset (parse-vec/u8 port))))
  1036. (#x01 (make-data #f 'passive #f #f (parse-vec/u8 port)))
  1037. (#x02 (let* ((mem (get-uleb port))
  1038. (offset (parse-expr port)))
  1039. (make-data #f 'active mem offset (parse-vec/u8 port))))
  1040. (byte (error "unexpected data segment kind" byte))))
  1041. (parse-vec port parse-segment))
  1042. (define (parse-section port code parse default)
  1043. (if (match-u8 port code)
  1044. (call-with-input-bytevector
  1045. (parse-vec/u8 port)
  1046. (lambda (port)
  1047. (let ((parsed (parse port)))
  1048. (unless (eof-object? (lookahead-u8 port))
  1049. (error "failed to consume bytes in section" code))
  1050. parsed)))
  1051. (default)))
  1052. (define (parse-names port)
  1053. (define (parse-id port)
  1054. (string->symbol (string-append "$" (get-name port))))
  1055. (define (parse-name-map port)
  1056. (parse-vec port (lambda (port)
  1057. (cons (get-uleb port) (parse-id port)))))
  1058. (define (parse-indirect-name-map port)
  1059. (parse-vec port (lambda (port)
  1060. (cons (get-uleb port) (parse-name-map port)))))
  1061. (define (parse-subsection port)
  1062. (match (get-u8 port)
  1063. (0
  1064. (cons 0 (call-with-input-bytevector (parse-vec/u8 port)
  1065. parse-id)))
  1066. ((and n (or 1 4 5 6 7 8 9 11))
  1067. (cons n (call-with-input-bytevector (parse-vec/u8 port)
  1068. parse-name-map)))
  1069. ((and n (or 2 3 10))
  1070. (cons n (call-with-input-bytevector (parse-vec/u8 port)
  1071. parse-indirect-name-map)))
  1072. (n (error "unexpected name subsection" n))))
  1073. (let ((subs (let loop ()
  1074. (if (eof-object? (lookahead-u8 port))
  1075. '()
  1076. (cons (parse-subsection port) (loop))))))
  1077. (define (lookup id default)
  1078. (or (assq-ref subs id) default))
  1079. (make-names (lookup 0 #f)
  1080. (lookup 1 '())
  1081. (lookup 2 '())
  1082. (lookup 3 '())
  1083. (lookup 4 '())
  1084. (lookup 5 '())
  1085. (lookup 6 '())
  1086. (lookup 7 '())
  1087. (lookup 8 '())
  1088. (lookup 9 '())
  1089. (lookup 10 '())
  1090. (lookup 11 '()))))
  1091. (define (parse-custom port custom)
  1092. (match (parse-section port #x00
  1093. (lambda (port)
  1094. (let ((name (get-name port)))
  1095. (if (string=? name "name")
  1096. (parse-names port)
  1097. (make-custom name (get-bytevector-all port)))))
  1098. (lambda () #f))
  1099. (#f custom)
  1100. (sec (parse-custom port (cons sec custom)))))
  1101. (define-syntax-rule (parse-sections ((custom 0 parse-custom custom-init)
  1102. (sec code parse default)
  1103. ...)
  1104. body ...)
  1105. (let ((custom custom-init))
  1106. (let*-values (((custom sec)
  1107. (let ((custom (parse-custom port custom)))
  1108. (values custom
  1109. (parse-section port code parse
  1110. (lambda () default)))))
  1111. ...)
  1112. (let ((custom (parse-custom port custom)))
  1113. body ...))))
  1114. (let ((bytes (get-bytes port 8)))
  1115. (unless (equal? bytes #vu8(#x00 #x61 #x73 #x6D #x01 #x00 #x00 #x00))
  1116. (error "unexpected wasm header" bytes)))
  1117. (parse-sections ((custom 0 parse-custom '())
  1118. (types 1 parse-types '())
  1119. (imports 2 parse-imports '())
  1120. (func-decls 3 parse-func-decls '())
  1121. (tables 4 parse-tables '())
  1122. (memories 5 parse-memories '())
  1123. (tags 13 parse-tags '())
  1124. (strings 14 parse-strings '())
  1125. (globals 6 parse-globals '())
  1126. (exports 7 parse-exports '())
  1127. (start 8 parse-start #f)
  1128. (elems 9 parse-elems '())
  1129. (data-count 12 parse-data-count #f)
  1130. (func-defs 10 parse-func-bodies '())
  1131. (data 11 parse-data '()))
  1132. (let* ((flattened-types (let lp ((types types))
  1133. (match types
  1134. (() '())
  1135. ((($ <rec-group> members) . types)
  1136. (append members (lp types)))
  1137. ((type . types) (cons type (lp types))))))
  1138. (ntypes (length flattened-types)))
  1139. (define (resolve-type-use idx)
  1140. (unless (< idx ntypes)
  1141. (error "type index out of bounds"))
  1142. (make-type-use idx (type-val (list-ref flattened-types idx))))
  1143. (define (resolve-import-type-use import)
  1144. (match import
  1145. (($ <import> mod name 'func id ($ <type-use> idx #f))
  1146. (make-import mod name 'func id (resolve-type-use idx)))
  1147. (($ <import> mod name 'tag id
  1148. ($ <tag-type> attribute ($ <type-use> idx #f)))
  1149. (make-import mod name 'tag id
  1150. (make-tag-type attribute (resolve-type-use idx))))
  1151. (_ import)))
  1152. (unless (= (length func-decls) (length func-defs))
  1153. (error "should be as many func decls as defs"))
  1154. (when data-count
  1155. (unless (= (length data) data-count)
  1156. (error "bad data-count" data-count)))
  1157. (make-wasm #f
  1158. types
  1159. (map resolve-import-type-use imports)
  1160. (map (match-lambda*
  1161. ((($ <type-use> idx #f)
  1162. ($ <func> #f #f locals body))
  1163. (make-func #f (resolve-type-use idx) locals body)))
  1164. func-decls
  1165. func-defs)
  1166. tables
  1167. memories
  1168. globals
  1169. exports
  1170. start
  1171. elems
  1172. data
  1173. (map (match-lambda
  1174. (($ <tag> #f ($ <tag-type> attribute ($ <type-use> idx #f)))
  1175. (let ((type (resolve-type-use idx)))
  1176. (make-tag #f (make-tag-type attribute type)))))
  1177. tags)
  1178. strings
  1179. custom))))
  1180. ;;; Local Variables:
  1181. ;;; eval: (put 'parse-sections 'scheme-indent-function 1)
  1182. ;;; End: