parse.scm 50 KB

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