parse.scm 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  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) ())))
  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. (label (parse-idx))
  501. (rt1 (make-ref-type (logtest 1 flags)
  502. (parse-heap-type port)))
  503. (rt2 (make-ref-type (logtest 2 flags)
  504. (parse-heap-type port))))
  505. (k `(br_on_cast ,label ,rt1 ,rt2))))
  506. (25 (let* ((flags (get-u8 port))
  507. (label (parse-idx))
  508. (rt1 (make-ref-type (logtest 1 flags)
  509. (parse-heap-type port)))
  510. (rt2 (make-ref-type (logtest 2 flags)
  511. (parse-heap-type port))))
  512. (k `(br_on_cast_fail ,label ,rt1 ,rt2))))
  513. (26 (k `(extern.internalize)))
  514. (27 (k `(extern.externalize)))
  515. (28 (k `(ref.i31)))
  516. (29 (k `(i31.get_s)))
  517. (30 (k `(i31.get_u)))
  518. (#x80 (k `(string.new_utf8 ,(parse-idx))))
  519. (#x81 (k `(string.new_wtf16 ,(parse-idx))))
  520. (#x82 (k `(string.const ,(parse-idx))))
  521. (#x83 (k `(string.measure_utf8)))
  522. (#x84 (k `(string.measure_wtf8)))
  523. (#x85 (k `(string.measure_wtf16)))
  524. (#x86 (k `(string.encode_utf8 ,(parse-idx))))
  525. (#x87 (k `(string.encode_wtf16 ,(parse-idx))))
  526. (#x88 (k `(string.concat)))
  527. (#x89 (k `(string.eq)))
  528. (#x8a (k `(string.is_usv_sequence)))
  529. (#x8b (k `(string.new_lossy_utf8 ,(parse-idx))))
  530. (#x8c (k `(string.new_wtf8 ,(parse-idx))))
  531. (#x8d (k `(string.encode_lossy_utf8 ,(parse-idx))))
  532. (#x8e (k `(string.encode_wtf8 ,(parse-idx))))
  533. (#x90 (k `(string.as_wtf8)))
  534. (#x91 (k `(stringview_wtf8.advance)))
  535. (#x92 (k `(stringview_wtf8.encode_utf8 ,(parse-idx))))
  536. (#x93 (k `(stringview_wtf8.slice)))
  537. (#x94 (k `(stringview_wtf8.encode_lossy_utf8 ,(parse-idx))))
  538. (#x95 (k `(stringview_wtf8.encode_wtf8 ,(parse-idx))))
  539. (#x98 (k `(string.as_wtf16)))
  540. (#x99 (k `(stringview_wtf16.length)))
  541. (#x9a (k `(stringview_wtf16.get_codeunit)))
  542. (#x9b (k `(stringview_wtf16.encode ,(parse-idx))))
  543. (#x9c (k `(stringview_wtf16.slice)))
  544. (#xa0 (k `(string.as_iter)))
  545. (#xa1 (k `(stringview_iter.next)))
  546. (#xa2 (k `(stringview_iter.advance)))
  547. (#xa3 (k `(stringview_iter.rewind)))
  548. (#xa4 (k `(stringview_iter.slice)))
  549. (#xa8 (k `(string.compare)))
  550. (#xa9 (k `(string.from_code_point)))
  551. (#xb0 (k `(string.new_utf8_array)))
  552. (#xb1 (k `(string.new_wtf16_array)))
  553. (#xb2 (k `(string.encode_utf8_array)))
  554. (#xb3 (k `(string.encode_wtf16_array)))
  555. (#xb4 (k `(string.new_lossy_utf8_array)))
  556. (#xb5 (k `(string.new_wtf8_array)))
  557. (#xb6 (k `(string.encode_lossy_utf8_array)))
  558. (#xb7 (k `(string.encode_wtf8_array)))
  559. (idx (error "unexpected GC opcode" idx))))
  560. (#xfc
  561. (match (get-uleb port)
  562. (#x00 (k `(i32.trunc_sat_f32_s)))
  563. (#x01 (k `(i32.trunc_sat_f32_u)))
  564. (#x02 (k `(i32.trunc_sat_f64_s)))
  565. (#x03 (k `(i32.trunc_sat_f64_u)))
  566. (#x04 (k `(i64.trunc_sat_f32_s)))
  567. (#x05 (k `(i64.trunc_sat_f32_u)))
  568. (#x06 (k `(i64.trunc_sat_f64_s)))
  569. (#x07 (k `(i64.trunc_sat_f64_u)))
  570. (#x08 (let* ((data (parse-idx))
  571. (mem (parse-idx)))
  572. (k `(memory.init ,data ,mem))))
  573. (#x09 (k `(data.drop ,(parse-idx))))
  574. (#x0a (let* ((dst (parse-idx))
  575. (src (parse-idx)))
  576. (k `(memory.copy ,dst ,src))))
  577. (#x0b (k `(memory.fill ,(parse-idx))))
  578. (#x0c (let* ((elem (parse-idx))
  579. (table (parse-idx)))
  580. (k `(table.init ,elem ,table))))
  581. (#x0d (k `(elem.drop ,(parse-idx))))
  582. (#x0e (let* ((dst (parse-idx))
  583. (src (parse-idx)))
  584. (k `(table.copy ,dst ,src))))
  585. (#x0f (k `(table.grow ,(get-uleb port))))
  586. (#x10 (k `(table.size ,(get-uleb port))))
  587. (#x11 (k `(table.fill ,(get-uleb port))))
  588. (idx (error "unexpected misc instruction" idx))))
  589. (#xfd
  590. (match (get-uleb port)
  591. (#x00 (k `(v128.load ,(parse-mem-arg))))
  592. (#x01 (k `(v128.load8x8_s ,(parse-mem-arg))))
  593. (#x02 (k `(v128.load8x8_u ,(parse-mem-arg))))
  594. (#x03 (k `(v128.load16x4_s ,(parse-mem-arg))))
  595. (#x04 (k `(v128.load16x4_u ,(parse-mem-arg))))
  596. (#x05 (k `(v128.load32x2_s ,(parse-mem-arg))))
  597. (#x06 (k `(v128.load32x2_u ,(parse-mem-arg))))
  598. (#x07 (k `(v128.load8_splat ,(parse-mem-arg))))
  599. (#x08 (k `(v128.load16_splat ,(parse-mem-arg))))
  600. (#x09 (k `(v128.load32_splat ,(parse-mem-arg))))
  601. (#x0a (k `(v128.load64_splat ,(parse-mem-arg))))
  602. (#x0b (k `(v128.store ,(parse-mem-arg))))
  603. (#x0c (k `(v128.const ,(get-bytes port 16))))
  604. (#x0d (k `(i8x16.shuffle ,(get-bytes port 16))))
  605. (#x0e (k `(i8x16.swizzle)))
  606. (#x0f (k `(i8x16.splat)))
  607. (#x10 (k `(i16x8.splat)))
  608. (#x11 (k `(i32x4.splat)))
  609. (#x12 (k `(i64x2.splat)))
  610. (#x13 (k `(f32x4.splat)))
  611. (#x14 (k `(f64x2.splat)))
  612. (#x15 (k `(i8x16.extract_lane_s ,(get-u8 port))))
  613. (#x16 (k `(i8x16.extract_lane_u ,(get-u8 port))))
  614. (#x17 (k `(i8x16.replace_lane ,(get-u8 port))))
  615. (#x18 (k `(i16x8.extract_lane_s ,(get-u8 port))))
  616. (#x19 (k `(i16x8.extract_lane_u ,(get-u8 port))))
  617. (#x1a (k `(i16x8.replace_lane ,(get-u8 port))))
  618. (#x1b (k `(i32x4.extract_lane ,(get-u8 port))))
  619. (#x1c (k `(i32x4.replace_lane ,(get-u8 port))))
  620. (#x1d (k `(i64x2.extract_lane ,(get-u8 port))))
  621. (#x1e (k `(i64x2.replace_lane ,(get-u8 port))))
  622. (#x1f (k `(f32x4.extract_lane ,(get-u8 port))))
  623. (#x20 (k `(f32x4.replace_lane ,(get-u8 port))))
  624. (#x21 (k `(f64x2.extract_lane ,(get-u8 port))))
  625. (#x22 (k `(f64x2.replace_lane ,(get-u8 port))))
  626. (#x23 (k `(i8x16.eq)))
  627. (#x24 (k `(i8x16.ne)))
  628. (#x25 (k `(i8x16.lt_s)))
  629. (#x26 (k `(i8x16.lt_u)))
  630. (#x27 (k `(i8x16.gt_s)))
  631. (#x28 (k `(i8x16.gt_u)))
  632. (#x29 (k `(i8x16.le_s)))
  633. (#x2a (k `(i8x16.le_u)))
  634. (#x2b (k `(i8x16.ge_s)))
  635. (#x2c (k `(i8x16.ge_u)))
  636. (#x2d (k `(i16x8.eq)))
  637. (#x2e (k `(i16x8.ne)))
  638. (#x2f (k `(i16x8.lt_s)))
  639. (#x30 (k `(i16x8.lt_u)))
  640. (#x31 (k `(i16x8.gt_s)))
  641. (#x32 (k `(i16x8.gt_u)))
  642. (#x33 (k `(i16x8.le_s)))
  643. (#x34 (k `(i16x8.le_u)))
  644. (#x35 (k `(i16x8.ge_s)))
  645. (#x36 (k `(i16x8.ge_u)))
  646. (#x37 (k `(i32x4.eq)))
  647. (#x38 (k `(i32x4.ne)))
  648. (#x39 (k `(i32x4.lt_s)))
  649. (#x3a (k `(i32x4.lt_u)))
  650. (#x3b (k `(i32x4.gt_s)))
  651. (#x3c (k `(i32x4.gt_u)))
  652. (#x3d (k `(i32x4.le_s)))
  653. (#x3e (k `(i32x4.le_u)))
  654. (#x3f (k `(i32x4.ge_s)))
  655. (#x40 (k `(i32x4.ge_u)))
  656. (#x41 (k `(f32x4.eq)))
  657. (#x42 (k `(f32x4.ne)))
  658. (#x43 (k `(f32x4.lt)))
  659. (#x44 (k `(f32x4.gt)))
  660. (#x45 (k `(f32x4.le)))
  661. (#x46 (k `(f32x4.ge)))
  662. (#x47 (k `(f64x2.eq)))
  663. (#x48 (k `(f64x2.ne)))
  664. (#x49 (k `(f64x2.lt)))
  665. (#x4a (k `(f64x2.gt)))
  666. (#x4b (k `(f64x2.le)))
  667. (#x4c (k `(f64x2.ge)))
  668. (#x4d (k `(v128.not)))
  669. (#x4e (k `(v128.and)))
  670. (#x4f (k `(v128.andnot)))
  671. (#x50 (k `(v128.or)))
  672. (#x51 (k `(v128.xor)))
  673. (#x52 (k `(v128.bitselect)))
  674. (#x53 (k `(v128.any_true)))
  675. (#x54 (let* ((mem-arg (parse-mem-arg))
  676. (lane (get-u8 port)))
  677. (k `(v128.load8_lane ,mem-arg ,lane))))
  678. (#x55 (let* ((mem-arg (parse-mem-arg))
  679. (lane (get-u8 port)))
  680. (k `(v128.load16_lane ,mem-arg ,lane))))
  681. (#x56 (let* ((mem-arg (parse-mem-arg))
  682. (lane (get-u8 port)))
  683. (k `(v128.load32_lane ,mem-arg ,lane))))
  684. (#x57 (let* ((mem-arg (parse-mem-arg))
  685. (lane (get-u8 port)))
  686. (k `(v128.load64_lane ,mem-arg ,lane))))
  687. (#x58 (let* ((mem-arg (parse-mem-arg))
  688. (lane (get-u8 port)))
  689. (k `(v128.store8_lane ,mem-arg ,lane))))
  690. (#x59 (let* ((mem-arg (parse-mem-arg))
  691. (lane (get-u8 port)))
  692. (k `(v128.store16_lane ,mem-arg ,lane))))
  693. (#x5a (let* ((mem-arg (parse-mem-arg))
  694. (lane (get-u8 port)))
  695. (k `(v128.store32_lane ,mem-arg ,lane))))
  696. (#x5b (let* ((mem-arg (parse-mem-arg))
  697. (lane (get-u8 port)))
  698. (k `(v128.store64_lane ,mem-arg ,lane))))
  699. (#x5c (k `(v128.load32_zero ,(parse-mem-arg))))
  700. (#x5d (k `(v128.load64_zero ,(parse-mem-arg))))
  701. (#x5e (k `(f32x4.demote_f64x2_zero)))
  702. (#x5f (k `(f64x2.promote_low_f32x4)))
  703. (#x60 (k `(i8x16.abs)))
  704. (#x61 (k `(i8x16.neg)))
  705. (#x62 (k `(i8x16.popcnt)))
  706. (#x63 (k `(i8x16.all_true)))
  707. (#x64 (k `(i8x16.bitmask)))
  708. (#x65 (k `(i8x16.narrow_i16x8_s)))
  709. (#x66 (k `(i8x16.narrow_i16x8_u)))
  710. (#x67 (k `(f32x4.ceil)))
  711. (#x68 (k `(f32x4.floor)))
  712. (#x69 (k `(f32x4.trunc)))
  713. (#x6a (k `(f32x4.nearest)))
  714. (#x6b (k `(i8x16.shl)))
  715. (#x6c (k `(i8x16.shr_s)))
  716. (#x6d (k `(i8x16.shr_u)))
  717. (#x6e (k `(i8x16.add)))
  718. (#x6f (k `(i8x16.add_sat_s)))
  719. (#x70 (k `(i8x16.add_sat_u)))
  720. (#x71 (k `(i8x16.sub)))
  721. (#x72 (k `(i8x16.sub_sat_s)))
  722. (#x73 (k `(i8x16.sub_sat_u)))
  723. (#x74 (k `(f64x2.ceil)))
  724. (#x75 (k `(f64x2.floor)))
  725. (#x76 (k `(i8x16.min_s)))
  726. (#x77 (k `(i8x16.min_u)))
  727. (#x78 (k `(i8x16.max_s)))
  728. (#x79 (k `(i8x16.max_u)))
  729. (#x7a (k `(f64x2.trunc)))
  730. (#x7b (k `(i8x16.avgr_u)))
  731. (#x7c (k `(i16x8.extadd_pairwise_i8x16_s)))
  732. (#x7d (k `(i16x8.extadd_pairwise_i8x16_u)))
  733. (#x7e (k `(i32x4.extadd_pairwise_i16x8_s)))
  734. (#x7f (k `(i32x4.extadd_pairwise_i16x8_u)))
  735. (#x80 (k `(i16x8.abs)))
  736. (#x81 (k `(i16x8.neg)))
  737. (#x82 (k `(i16x8.q15mulr_sat_s)))
  738. (#x83 (k `(i16x8.all_true)))
  739. (#x84 (k `(i16x8.bitmask)))
  740. (#x85 (k `(i16x8.narrow_i32x4_s)))
  741. (#x86 (k `(i16x8.narrow_i32x4_u)))
  742. (#x87 (k `(i16x8.extend_low_i8x16_s)))
  743. (#x88 (k `(i16x8.extend_high_i8x16_s)))
  744. (#x89 (k `(i16x8.extend_low_i8x16_u)))
  745. (#x8a (k `(i16x8.extend_high_i8x16_u)))
  746. (#x8b (k `(i16x8.shl)))
  747. (#x8c (k `(i16x8.shr_s)))
  748. (#x8d (k `(i16x8.shr_u)))
  749. (#x8e (k `(i16x8.add)))
  750. (#x8f (k `(i16x8.add_sat_s)))
  751. (#x90 (k `(i16x8.add_sat_u)))
  752. (#x91 (k `(i16x8.sub)))
  753. (#x92 (k `(i16x8.sub_sat_s)))
  754. (#x93 (k `(i16x8.sub_sat_u)))
  755. (#x94 (k `(f64x2.nearest)))
  756. (#x95 (k `(i16x8.mul)))
  757. (#x96 (k `(i16x8.min_s)))
  758. (#x97 (k `(i16x8.min_u)))
  759. (#x98 (k `(i16x8.max_s)))
  760. (#x99 (k `(i16x8.max_u)))
  761. (#x9b (k `(i16x8.avgr_u)))
  762. (#x9c (k `(i16x8.extmul_low_i8x16_s)))
  763. (#x9d (k `(i16x8.extmul_high_i8x16_s)))
  764. (#x9e (k `(i16x8.extmul_low_i8x16_u)))
  765. (#x9f (k `(i16x8.extmul_high_i8x16_u)))
  766. (#xa0 (k `(i32x4.abs)))
  767. (#xa1 (k `(i32x4.neg)))
  768. (#xa3 (k `(i32x4.all_true)))
  769. (#xa4 (k `(i32x4.bitmask)))
  770. (#xa7 (k `(i32x4.extend_low_i16x8_s)))
  771. (#xa8 (k `(i32x4.extend_high_i16x8_s)))
  772. (#xa9 (k `(i32x4.extend_low_i16x8_u)))
  773. (#xaa (k `(i32x4.extend_high_i16x8_u)))
  774. (#xab (k `(i32x4.shl)))
  775. (#xac (k `(i32x4.shr_s)))
  776. (#xad (k `(i32x4.shr_u)))
  777. (#xae (k `(i32x4.add)))
  778. (#xb1 (k `(i32x4.sub)))
  779. (#xb5 (k `(i32x4.mul)))
  780. (#xb6 (k `(i32x4.min_s)))
  781. (#xb7 (k `(i32x4.min_u)))
  782. (#xb8 (k `(i32x4.max_s)))
  783. (#xb9 (k `(i32x4.max_u)))
  784. (#xba (k `(i32x4.dot_i16x8_s)))
  785. (#xbc (k `(i32x4.extmul_low_i16x8_s)))
  786. (#xbd (k `(i32x4.extmul_high_i16x8_s)))
  787. (#xbe (k `(i32x4.extmul_low_i16x8_u)))
  788. (#xbf (k `(i32x4.extmul_high_i16x8_u)))
  789. (#xc0 (k `(i64x2.abs)))
  790. (#xc1 (k `(i64x2.neg)))
  791. (#xc3 (k `(i64x2.all_true)))
  792. (#xc4 (k `(i64x2.bitmask)))
  793. (#xc7 (k `(i64x2.extend_low_i32x4_s)))
  794. (#xc8 (k `(i64x2.extend_high_i32x4_s)))
  795. (#xc9 (k `(i64x2.extend_low_i32x4_u)))
  796. (#xca (k `(i64x2.extend_high_i32x4_u)))
  797. (#xcb (k `(i64x2.shl)))
  798. (#xcc (k `(i64x2.shr_s)))
  799. (#xcd (k `(i64x2.shr_u)))
  800. (#xce (k `(i64x2.add)))
  801. (#xd1 (k `(i64x2.sub)))
  802. (#xd5 (k `(i64x2.mul)))
  803. (#xd6 (k `(i64x2.eq)))
  804. (#xd7 (k `(i64x2.ne)))
  805. (#xd8 (k `(i64x2.lt_s)))
  806. (#xd9 (k `(i64x2.gt_s)))
  807. (#xda (k `(i64x2.le_s)))
  808. (#xdb (k `(i64x2.ge_s)))
  809. (#xdc (k `(i64x2.extmul_low_i32x4_s)))
  810. (#xdd (k `(i64x2.extmul_high_i32x4_s)))
  811. (#xde (k `(i64x2.extmul_low_i32x4_u)))
  812. (#xdf (k `(i64x2.extmul_high_i32x4_u)))
  813. (#xe0 (k `(f32x4.abs)))
  814. (#xe1 (k `(f32x4.neg)))
  815. (#xe3 (k `(f32x4.sqrt)))
  816. (#xe4 (k `(f32x4.add)))
  817. (#xe5 (k `(f32x4.sub)))
  818. (#xe6 (k `(f32x4.mul)))
  819. (#xe7 (k `(f32x4.div)))
  820. (#xe8 (k `(f32x4.min)))
  821. (#xe9 (k `(f32x4.max)))
  822. (#xea (k `(f32x4.pmin)))
  823. (#xeb (k `(f32x4.pmax)))
  824. (#xec (k `(f64x2.abs)))
  825. (#xed (k `(f64x2.neg)))
  826. (#xef (k `(f64x2.sqrt)))
  827. (#xf0 (k `(f64x2.add)))
  828. (#xf1 (k `(f64x2.sub)))
  829. (#xf2 (k `(f64x2.mul)))
  830. (#xf3 (k `(f64x2.div)))
  831. (#xf4 (k `(f64x2.min)))
  832. (#xf5 (k `(f64x2.max)))
  833. (#xf6 (k `(f64x2.pmin)))
  834. (#xf7 (k `(f64x2.pmax)))
  835. (#xf8 (k `(i32x4.trunc_sat_f32x4_s)))
  836. (#xf9 (k `(i32x4.trunc_sat_f32x4_u)))
  837. (#xfa (k `(f32x4.convert_i32x4_s)))
  838. (#xfb (k `(f32x4.convert_i32x4_u)))
  839. (#xfc (k `(i32x4.trunc_sat_f64x2_s_zero)))
  840. (#xfd (k `(i32x4.trunc_sat_f64x2_u_zero)))
  841. (#xfe (k `(f64x2.convert_low_i32x4_s)))
  842. (#xff (k `(f64x2.convert_low_i32x4_u)))
  843. (#x100 (k `(i8x16.relaxed_swizzle)))
  844. (#x101 (k `(i32x4.relaxed_trunc_f32x4_s)))
  845. (#x102 (k `(i32x4.relaxed_trunc_f32x4_u)))
  846. (#x103 (k `(i32x4.relaxed_trunc_f64x2_s_zero)))
  847. (#x104 (k `(i32x4.relaxed_trunc_f64x2_u_zero)))
  848. (#x105 (k `(f32x4.qfma)))
  849. (#x106 (k `(f32x4.qfms)))
  850. (#x107 (k `(f64x2.qfma)))
  851. (#x108 (k `(f64x2.qfms)))
  852. (#x109 (k `(i8x16.relaxed_laneselect)))
  853. (#x10a (k `(i16x8.relaxed_laneselect)))
  854. (#x10b (k `(i32x4.relaxed_laneselect)))
  855. (#x10c (k `(i64x2.relaxed_laneselect)))
  856. (#x10d (k `(f32x4.relaxed_min)))
  857. (#x10e (k `(f32x4.relaxed_max)))
  858. (#x10f (k `(f64x2.relaxed_min)))
  859. (#x110 (k `(f64x2.relaxed_max)))
  860. (#x111 (k `(i16x8.relaxed_q15mulr_s)))
  861. (#x112 (k `(i16x8.dot_i8x16_i7x16_s)))
  862. (#x113 (k `(i32x4.dot_i8x16_i7x16_add_s)))
  863. (idx (error "unexpected simd instruction" idx))))
  864. (#xfe
  865. (match (get-uleb port)
  866. (#x00 (k `(memory.atomic.notify ,(parse-mem-arg))))
  867. (#x01 (k `(memory.atomic.wait32 ,(parse-mem-arg))))
  868. (#x02 (k `(memory.atomic.wait64 ,(parse-mem-arg))))
  869. (#x03 (k `(atomic.fence))) ;; no mem arg
  870. (#x10 (k `(i32.atomic.load ,(parse-mem-arg))))
  871. (#x11 (k `(i64.atomic.load ,(parse-mem-arg))))
  872. (#x12 (k `(i32.atomic.load8_u ,(parse-mem-arg))))
  873. (#x13 (k `(i32.atomic.load16_u ,(parse-mem-arg))))
  874. (#x14 (k `(i64.atomic.load8_u ,(parse-mem-arg))))
  875. (#x15 (k `(i64.atomic.load16_u ,(parse-mem-arg))))
  876. (#x16 (k `(i64.atomic.load32_u ,(parse-mem-arg))))
  877. (#x17 (k `(i32.atomic.store ,(parse-mem-arg))))
  878. (#x18 (k `(i64.atomic.store ,(parse-mem-arg))))
  879. (#x19 (k `(i32.atomic.store8 ,(parse-mem-arg))))
  880. (#x1a (k `(i32.atomic.store16 ,(parse-mem-arg))))
  881. (#x1b (k `(i64.atomic.store8 ,(parse-mem-arg))))
  882. (#x1c (k `(i64.atomic.store16 ,(parse-mem-arg))))
  883. (#x1d (k `(i64.atomic.store32 ,(parse-mem-arg))))
  884. (#x1e (k `(i32.atomic.rmw.add ,(parse-mem-arg))))
  885. (#x1f (k `(i64.atomic.rmw.add ,(parse-mem-arg))))
  886. (#x20 (k `(i32.atomic.rmw8.add_u ,(parse-mem-arg))))
  887. (#x21 (k `(i32.atomic.rmw16.add_u ,(parse-mem-arg))))
  888. (#x22 (k `(i64.atomic.rmw8.add_u ,(parse-mem-arg))))
  889. (#x23 (k `(i64.atomic.rmw16.add_u ,(parse-mem-arg))))
  890. (#x24 (k `(i64.atomic.rmw32.add_u ,(parse-mem-arg))))
  891. (#x25 (k `(i32.atomic.rmw.sub ,(parse-mem-arg))))
  892. (#x26 (k `(i64.atomic.rmw.sub ,(parse-mem-arg))))
  893. (#x27 (k `(i32.atomic.rmw8.sub_u ,(parse-mem-arg))))
  894. (#x28 (k `(i32.atomic.rmw16.sub_u ,(parse-mem-arg))))
  895. (#x29 (k `(i64.atomic.rmw8.sub_u ,(parse-mem-arg))))
  896. (#x2a (k `(i64.atomic.rmw16.sub_u ,(parse-mem-arg))))
  897. (#x2b (k `(i64.atomic.rmw32.sub_u ,(parse-mem-arg))))
  898. (#x2c (k `(i32.atomic.rmw.and ,(parse-mem-arg))))
  899. (#x2d (k `(i64.atomic.rmw.and ,(parse-mem-arg))))
  900. (#x2e (k `(i32.atomic.rmw8.and_u ,(parse-mem-arg))))
  901. (#x2f (k `(i32.atomic.rmw16.and_u ,(parse-mem-arg))))
  902. (#x30 (k `(i64.atomic.rmw8.and_u ,(parse-mem-arg))))
  903. (#x31 (k `(i64.atomic.rmw16.and_u ,(parse-mem-arg))))
  904. (#x32 (k `(i64.atomic.rmw32.and_u ,(parse-mem-arg))))
  905. (#x33 (k `(i32.atomic.rmw.or ,(parse-mem-arg))))
  906. (#x34 (k `(i64.atomic.rmw.or ,(parse-mem-arg))))
  907. (#x35 (k `(i32.atomic.rmw8.or_u ,(parse-mem-arg))))
  908. (#x36 (k `(i32.atomic.rmw16.or_u ,(parse-mem-arg))))
  909. (#x37 (k `(i64.atomic.rmw8.or_u ,(parse-mem-arg))))
  910. (#x38 (k `(i64.atomic.rmw16.or_u ,(parse-mem-arg))))
  911. (#x39 (k `(i64.atomic.rmw32.or_u ,(parse-mem-arg))))
  912. (#x3a (k `(i32.atomic.rmw.xor ,(parse-mem-arg))))
  913. (#x3b (k `(i64.atomic.rmw.xor ,(parse-mem-arg))))
  914. (#x3c (k `(i32.atomic.rmw8.xor_u ,(parse-mem-arg))))
  915. (#x3d (k `(i32.atomic.rmw16.xor_u ,(parse-mem-arg))))
  916. (#x3e (k `(i64.atomic.rmw8.xor_u ,(parse-mem-arg))))
  917. (#x3f (k `(i64.atomic.rmw16.xor_u ,(parse-mem-arg))))
  918. (#x40 (k `(i64.atomic.rmw32.xor_u ,(parse-mem-arg))))
  919. (#x41 (k `(i32.atomic.rmw.xchg ,(parse-mem-arg))))
  920. (#x42 (k `(i64.atomic.rmw.xchg ,(parse-mem-arg))))
  921. (#x43 (k `(i32.atomic.rmw8.xchg_u ,(parse-mem-arg))))
  922. (#x44 (k `(i32.atomic.rmw16.xchg_u ,(parse-mem-arg))))
  923. (#x45 (k `(i64.atomic.rmw8.xchg_u ,(parse-mem-arg))))
  924. (#x46 (k `(i64.atomic.rmw16.xchg_u ,(parse-mem-arg))))
  925. (#x47 (k `(i64.atomic.rmw32.xchg_u ,(parse-mem-arg))))
  926. (#x48 (k `(i32.atomic.rmw.cmpxchg ,(parse-mem-arg))))
  927. (#x49 (k `(i64.atomic.rmw.cmpxchg ,(parse-mem-arg))))
  928. (#x4a (k `(i32.atomic.rmw8.cmpxchg_u ,(parse-mem-arg))))
  929. (#x4b (k `(i32.atomic.rmw16.cmpxchg_u ,(parse-mem-arg))))
  930. (#x4c (k `(i64.atomic.rmw8.cmpxchg_u ,(parse-mem-arg))))
  931. (#x4d (k `(i64.atomic.rmw16.cmpxchg_u ,(parse-mem-arg))))
  932. (#x4e (k `(i64.atomic.rmw32.cmpxchg_u ,(parse-mem-arg))))
  933. (idx (error "unexpected atomic instruction" idx))))
  934. (byte (error "unexpected opcode" byte)))))
  935. (define (parse-body)
  936. (let-values (((body end-tok) (parse-body*)))
  937. (match end-tok
  938. ('end body)
  939. (_ (error "unexpected token" end-tok)))))
  940. (parse-body))
  941. (define (parse-tables port)
  942. (define (parse-table port)
  943. (cond
  944. ((match-u8 port #x40)
  945. (expect-u8 port #x00)
  946. (let* ((type (parse-table-type port))
  947. (init (parse-expr port)))
  948. (make-table #f type init)))
  949. (else
  950. (make-table #f (parse-table-type port) #f))))
  951. (parse-vec port parse-table))
  952. (define (parse-memories port)
  953. (define (parse-memory port)
  954. (make-memory #f (parse-mem-type port)))
  955. (parse-vec port parse-memory))
  956. (define (parse-tag port)
  957. (make-tag #f (parse-tag-type port)))
  958. (define (parse-tags port)
  959. (parse-vec port parse-tag))
  960. (define (parse-strings port)
  961. (expect-u8 port #x00)
  962. (parse-vec port get-name))
  963. (define (parse-globals port)
  964. (define (parse-global port)
  965. (let ((type (parse-global-type port)))
  966. (make-global #f type (parse-expr port))))
  967. (parse-vec port parse-global))
  968. (define (parse-exports port)
  969. (define (parse-export port)
  970. (let* ((name (get-name port))
  971. (type (match (get-u8 port)
  972. (#x00 'func)
  973. (#x01 'table)
  974. (#x02 'memory)
  975. (#x03 'global)
  976. (#x04 'tag)
  977. (byte (error "unexpected byte" byte)))))
  978. (make-export name type (get-uleb port))))
  979. (parse-vec port parse-export))
  980. (define (parse-start port)
  981. (get-uleb port))
  982. (define (parse-elems port)
  983. (define (parse-elem port)
  984. (define (ref-funcs indexes)
  985. (map (lambda (idx) `((ref.func ,idx))) indexes))
  986. (match (get-u8 port)
  987. (#x00 (let* ((offset (parse-expr port)))
  988. (make-elem #f 'active 0 'funcref offset
  989. (ref-funcs (parse-vec port get-uleb)))))
  990. (#x01 (expect-u8 port #x00)
  991. (make-elem #f 'passive #f 'funcref #f
  992. (ref-funcs (parse-vec port get-uleb))))
  993. (#x02 (let* ((table (get-uleb port))
  994. (offset (parse-expr port)))
  995. (expect-u8 port #x00)
  996. (make-elem #f 'active table 'funcref offset
  997. (ref-funcs (parse-vec port get-uleb)))))
  998. (#x03 (expect-u8 port #x00)
  999. (make-elem #f 'declarative #f 'funcref #f
  1000. (ref-funcs (parse-vec port get-uleb))))
  1001. (#x04 (let ((offset (parse-expr port)))
  1002. (make-elem #f 'active 0 'funcref offset
  1003. (parse-vec port parse-expr))))
  1004. (#x05 (let ((type (parse-ref-type port)))
  1005. (make-elem #f 'passive #f type #f
  1006. (parse-vec port parse-expr))))
  1007. (#x06 (let ((table (get-uleb port))
  1008. (offset (parse-expr port))
  1009. (type (parse-ref-type port)))
  1010. (make-elem #f 'active table type offset
  1011. (parse-vec port parse-expr))))
  1012. (#x07 (let ((type (parse-ref-type port)))
  1013. (make-elem #f 'declarative #f type #f
  1014. (parse-vec port parse-expr))))
  1015. (byte (error "unexpected byte" byte))))
  1016. (parse-vec port parse-elem))
  1017. (define (parse-func-bodies port)
  1018. (define (parse-code port)
  1019. (call-with-input-bytevector
  1020. (parse-vec/u8 port)
  1021. (lambda (port)
  1022. (define (parse-local port)
  1023. (let ((n (get-uleb port)))
  1024. (make-list n (make-local #f (parse-val-type port)))))
  1025. (let* ((locals (apply append (parse-vec port parse-local)))
  1026. (body (parse-expr port)))
  1027. (unless (eof-object? (lookahead-u8 port))
  1028. (error "unexpected trailing bytes in function"))
  1029. (make-func #f #f locals body)))))
  1030. (parse-vec port parse-code))
  1031. (define (parse-data-count port)
  1032. (get-uleb port))
  1033. (define (parse-data port)
  1034. (define (parse-segment port)
  1035. (match (get-u8 port)
  1036. (#x00 (let ((offset (parse-expr port)))
  1037. (make-data #f 'active 0 offset (parse-vec/u8 port))))
  1038. (#x01 (make-data #f 'passive #f #f (parse-vec/u8 port)))
  1039. (#x02 (let* ((mem (get-uleb port))
  1040. (offset (parse-expr port)))
  1041. (make-data #f 'active mem offset (parse-vec/u8 port))))
  1042. (byte (error "unexpected data segment kind" byte))))
  1043. (parse-vec port parse-segment))
  1044. (define (parse-section port code parse default)
  1045. (if (match-u8 port code)
  1046. (call-with-input-bytevector
  1047. (parse-vec/u8 port)
  1048. (lambda (port)
  1049. (let ((parsed (parse port)))
  1050. (unless (eof-object? (lookahead-u8 port))
  1051. (error "failed to consume bytes in section" code))
  1052. parsed)))
  1053. (default)))
  1054. (define (parse-names port)
  1055. (define (parse-id port)
  1056. (string->symbol (string-append "$" (get-name port))))
  1057. (define (parse-name-map port)
  1058. (parse-vec port (lambda (port)
  1059. (cons (get-uleb port) (parse-id port)))))
  1060. (define (parse-indirect-name-map port)
  1061. (parse-vec port (lambda (port)
  1062. (cons (get-uleb port) (parse-name-map port)))))
  1063. (define (parse-subsection port)
  1064. (match (get-u8 port)
  1065. (0
  1066. (cons 0 (call-with-input-bytevector (parse-vec/u8 port)
  1067. parse-id)))
  1068. ((and n (or 1 4 5 6 7 8 9 11))
  1069. (cons n (call-with-input-bytevector (parse-vec/u8 port)
  1070. parse-name-map)))
  1071. ((and n (or 2 3 10))
  1072. (cons n (call-with-input-bytevector (parse-vec/u8 port)
  1073. parse-indirect-name-map)))
  1074. (n (error "unexpected name subsection" n))))
  1075. (let ((subs (let loop ()
  1076. (if (eof-object? (lookahead-u8 port))
  1077. '()
  1078. (cons (parse-subsection port) (loop))))))
  1079. (define (lookup id default)
  1080. (or (assq-ref subs id) default))
  1081. (make-names (lookup 0 #f)
  1082. (lookup 1 '())
  1083. (lookup 2 '())
  1084. (lookup 3 '())
  1085. (lookup 4 '())
  1086. (lookup 5 '())
  1087. (lookup 6 '())
  1088. (lookup 7 '())
  1089. (lookup 8 '())
  1090. (lookup 9 '())
  1091. (lookup 10 '())
  1092. (lookup 11 '()))))
  1093. (define (parse-custom port custom)
  1094. (match (parse-section port #x00
  1095. (lambda (port)
  1096. (let ((name (get-name port)))
  1097. (if (string=? name "name")
  1098. (parse-names port)
  1099. (make-custom name (get-bytevector-all port)))))
  1100. (lambda () #f))
  1101. (#f custom)
  1102. (sec (parse-custom port (cons sec custom)))))
  1103. (define-syntax-rule (parse-sections ((custom 0 parse-custom custom-init)
  1104. (sec code parse default)
  1105. ...)
  1106. body ...)
  1107. (let ((custom custom-init))
  1108. (let*-values (((custom sec)
  1109. (let ((custom (parse-custom port custom)))
  1110. (values custom
  1111. (parse-section port code parse
  1112. (lambda () default)))))
  1113. ...)
  1114. (let ((custom (parse-custom port custom)))
  1115. body ...))))
  1116. (let ((bytes (get-bytes port 8)))
  1117. (unless (equal? bytes #vu8(#x00 #x61 #x73 #x6D #x01 #x00 #x00 #x00))
  1118. (error "unexpected wasm header" bytes)))
  1119. (parse-sections ((custom 0 parse-custom '())
  1120. (types 1 parse-types '())
  1121. (imports 2 parse-imports '())
  1122. (func-decls 3 parse-func-decls '())
  1123. (tables 4 parse-tables '())
  1124. (memories 5 parse-memories '())
  1125. (tags 13 parse-tags '())
  1126. (strings 14 parse-strings '())
  1127. (globals 6 parse-globals '())
  1128. (exports 7 parse-exports '())
  1129. (start 8 parse-start #f)
  1130. (elems 9 parse-elems '())
  1131. (data-count 12 parse-data-count #f)
  1132. (func-defs 10 parse-func-bodies '())
  1133. (data 11 parse-data '()))
  1134. (let* ((flattened-types (let lp ((types types))
  1135. (match types
  1136. (() '())
  1137. ((($ <rec-group> members) . types)
  1138. (append members (lp types)))
  1139. ((type . types) (cons type (lp types))))))
  1140. (ntypes (length flattened-types)))
  1141. (define (resolve-type-use idx)
  1142. (unless (< idx ntypes)
  1143. (error "type index out of bounds"))
  1144. (make-type-use idx (type-val (list-ref flattened-types idx))))
  1145. (define (resolve-import-type-use import)
  1146. (match import
  1147. (($ <import> mod name 'func id ($ <type-use> idx #f))
  1148. (make-import mod name 'func id (resolve-type-use idx)))
  1149. (($ <import> mod name 'tag id
  1150. ($ <tag-type> attribute ($ <type-use> idx #f)))
  1151. (make-import mod name 'tag id
  1152. (make-tag-type attribute (resolve-type-use idx))))
  1153. (_ import)))
  1154. (unless (= (length func-decls) (length func-defs))
  1155. (error "should be as many func decls as defs"))
  1156. (when data-count
  1157. (unless (= (length data) data-count)
  1158. (error "bad data-count" data-count)))
  1159. (make-wasm #f
  1160. types
  1161. (map resolve-import-type-use imports)
  1162. (map (match-lambda*
  1163. ((($ <type-use> idx #f)
  1164. ($ <func> #f #f locals body))
  1165. (make-func #f (resolve-type-use idx) locals body)))
  1166. func-decls
  1167. func-defs)
  1168. tables
  1169. memories
  1170. globals
  1171. exports
  1172. start
  1173. elems
  1174. data
  1175. (map (match-lambda
  1176. (($ <tag> #f ($ <tag-type> attribute ($ <type-use> idx #f)))
  1177. (let ((type (resolve-type-use idx)))
  1178. (make-tag #f (make-tag-type attribute type)))))
  1179. tags)
  1180. strings
  1181. custom))))
  1182. ;;; Local Variables:
  1183. ;;; eval: (put 'parse-sections 'scheme-indent-function 1)
  1184. ;;; End: