wasmbincode.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. { This file is part of wasmbin - a collection of WebAssembly binary utils.
  2. Copyright (C) 2019, 2020 Dmitry Boyarintsev <[email protected]>
  3. Copyright (C) 2020 by the Free Pascal development team
  4. This source is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 2 of the License, or (at your option)
  7. any later version.
  8. This code is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  10. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  11. details.
  12. A copy of the GNU General Public License is available on the World Wide Web
  13. at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
  14. to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
  15. Boston, MA 02110-1335, USA.
  16. }
  17. unit wasmbincode;
  18. // WebAssembly instructions information
  19. // http://webassembly.github.io/spec/core/binary/instructions.html
  20. {$mode objfpc}{$H+}
  21. interface
  22. uses
  23. Classes, SysUtils, lebutils;
  24. const
  25. VALTYPE_NONE = $40;
  26. VALTYPE_I32 = $7F;
  27. VALTYPE_I64 = $7E;
  28. VALTYPE_F32 = $7D;
  29. VALTYPE_F64 = $7C;
  30. INST_TRAP = $00;
  31. // ..
  32. INST_IF = $04;
  33. INST_ELSE = $05;
  34. // ...
  35. INST_END = $0b;
  36. INST_block = $02;
  37. INST_loop = $03;
  38. INST_unreachable = $00;
  39. INST_nop = $01;
  40. INST_br = $0C;
  41. INST_br_if = $0D;
  42. INST_br_table = $0E;
  43. INST_return = $0F;
  44. INST_call = $10;
  45. INST_call_indirect = $11;
  46. //INST_if = $04;
  47. //INST_else = $05;
  48. //INST_end = $0B;
  49. INST_drop = $1A;
  50. INST_select = $1B;
  51. INST_local_get = $20;
  52. INST_local_set = $21;
  53. INST_local_tee = $22;
  54. INST_global_get = $23;
  55. INST_global_set = $24;
  56. INST_i32_load = $28;
  57. INST_i64_load = $29;
  58. INST_f32_load = $2a;
  59. INST_f64_load = $2b;
  60. INST_i32_load8_s = $2c;
  61. INST_i32_load8_u = $2d;
  62. INST_i32_load16_s = $2e;
  63. INST_i32_load16_u = $2f;
  64. INST_i64_load8_s = $30;
  65. INST_i64_load8_u = $31;
  66. INST_i64_load16_s = $32;
  67. INST_i64_load16_u = $33;
  68. INST_i64_load32_s = $34;
  69. INST_i64_load32_u = $35;
  70. INST_i32_store = $36;
  71. INST_i64_store = $37;
  72. INST_f32_store = $38;
  73. INST_f64_store = $39;
  74. INST_i32_store8 = $3a;
  75. INST_i32_store16 = $3b;
  76. INST_i64_store8 = $3c;
  77. INST_i64_store16 = $3d;
  78. INST_i64_store32 = $3e;
  79. INST_memory_size = $3f;
  80. INST_memory_grow = $40;
  81. INST_i32_const = $41;
  82. INST_i64_const = $42;
  83. INST_f32_const = $43;
  84. INST_f64_const = $44;
  85. INST_i32_clz = $67;
  86. INST_i32_ctz = $68;
  87. INST_i32_popcnt = $69;
  88. INST_i32_add = $6a;
  89. INST_i32_sub = $6b;
  90. INST_i32_mul = $6c;
  91. INST_i32_div_s = $6d;
  92. INST_i32_div_u = $6e;
  93. INST_i32_rem_s = $6f;
  94. INST_i32_rem_u = $70;
  95. INST_i32_and = $71;
  96. INST_i32_or = $72;
  97. INST_i32_xor = $73;
  98. INST_i32_shl = $74;
  99. INST_i32_shr_s = $75;
  100. INST_i32_shr_u = $76;
  101. INST_i32_rotl = $77;
  102. INST_i32_rotr = $78;
  103. INST_i64_clz = $79;
  104. INST_i64_ctz = $7a;
  105. INST_i64_popcnt = $7b;
  106. INST_i64_add = $7c;
  107. INST_i64_sub = $7d;
  108. INST_i64_mul = $7e;
  109. INST_i64_div_s = $7f;
  110. INST_i64_div_u = $80;
  111. INST_i64_rem_s = $81;
  112. INST_i64_rem_u = $82;
  113. INST_i64_and = $83;
  114. INST_i64_or = $84;
  115. INST_i64_xor = $85;
  116. INST_i64_shl = $86;
  117. INST_i64_shr_s = $87;
  118. INST_i64_shr_u = $88;
  119. INST_i64_rotl = $89;
  120. INST_i64_rotr = $8a;
  121. INST_f32_abs = $8b;
  122. INST_f32_neg = $8c;
  123. INST_f32_ceil = $8d;
  124. INST_f32_floor = $8e;
  125. INST_f32_trunc = $8f;
  126. INST_f32_nearest = $90;
  127. INST_f32_sqrt = $91;
  128. INST_f32_add = $92;
  129. INST_f32_sub = $93;
  130. INST_f32_mul = $94;
  131. INST_f32_div = $95;
  132. INST_f32_min = $96;
  133. INST_f32_max = $97;
  134. INST_f32_copysign = $98;
  135. INST_f64_abs = $99;
  136. INST_f64_neg = $9a;
  137. INST_f64_ceil = $9b;
  138. INST_f64_floor = $9c;
  139. INST_f64_trunc = $9d;
  140. INST_f64_nearest = $9e;
  141. INST_f64_sqrt = $9f;
  142. INST_f64_add = $a0;
  143. INST_f64_sub = $a1;
  144. INST_f64_mul = $a2;
  145. INST_f64_div = $a3;
  146. INST_f64_min = $a4;
  147. INST_f64_max = $a5;
  148. INST_f64_copysign = $a6;
  149. INST_i32_eqz = $45;
  150. INST_i32_eq = $46;
  151. INST_i32_ne = $47;
  152. INST_i32_lt_s = $48;
  153. INST_i32_lt_u = $49;
  154. INST_i32_gt_s = $4a;
  155. INST_i32_gt_u = $4b;
  156. INST_i32_le_s = $4c;
  157. INST_i32_le_u = $4d;
  158. INST_i32_ge_s = $4e;
  159. INST_i32_ge_u = $4f;
  160. INST_i64_eqz = $50;
  161. INST_i64_eq = $51;
  162. INST_i64_ne = $52;
  163. INST_i64_lt_s = $53;
  164. INST_i64_lt_u = $54;
  165. INST_i64_gt_s = $55;
  166. INST_i64_gt_u = $56;
  167. INST_i64_le_s = $57;
  168. INST_i64_le_u = $58;
  169. INST_i64_ge_s = $59;
  170. INST_i64_ge_u = $5a;
  171. INST_f32_eq = $5b;
  172. INST_f32_ne = $5c;
  173. INST_f32_lt = $5d;
  174. INST_f32_gt = $5e;
  175. INST_f32_le = $5f;
  176. INST_f32_ge = $60;
  177. INST_f64_eq = $61;
  178. INST_f64_ne = $62;
  179. INST_f64_lt = $63;
  180. INST_f64_gt = $64;
  181. INST_f64_le = $65;
  182. INST_f64_ge = $66;
  183. INST_i32_wrap_i64 = $a7;
  184. INST_i32_trunc_f32_s = $a8;
  185. INST_i32_trunc_f32_u = $a9;
  186. INST_i32_trunc_f64_s = $aa;
  187. INST_i32_trunc_f64_u = $ab;
  188. INST_i64_extend_i32_s = $ac;
  189. INST_i64_extend_i32_u = $ad;
  190. INST_i64_trunc_f32_s = $ae;
  191. INST_i64_trunc_f32_u = $af;
  192. INST_i64_trunc_f64_s = $b0;
  193. INST_i64_trunc_f64_u = $b1;
  194. INST_f32_convert_i32_s = $b2;
  195. INST_f32_convert_i32_u = $b3;
  196. INST_f32_convert_i64_s = $b4;
  197. INST_f32_convert_i64_u = $b5;
  198. INST_f32_demote_f64 = $b6;
  199. INST_f64_convert_i32_s = $b7;
  200. INST_f64_convert_i32_u = $b8;
  201. INST_f64_convert_i64_s = $b9;
  202. INST_f64_convert_i64_u = $ba;
  203. INST_f64_promote_f32 = $bb;
  204. INST_i32_reinterpret_f32 = $bc;
  205. INST_i64_reinterpret_f64 = $bd;
  206. INST_f32_reinterpret_i32 = $be;
  207. INST_f64_reinterpret_i64 = $bf;
  208. // ...
  209. INST_REINTERPRET_I64 = $BF;
  210. MIN_INST = INST_TRAP;
  211. MAX_INST = INST_REINTERPRET_I64;
  212. type
  213. TInstParamType = (ipNone,
  214. ipLeb, // label index or function index
  215. ipOfsAlign, // memory arguments, ask for offset + align
  216. ipi32, // signed Leb of maximum 4 bytes
  217. ipi64, // signed Leb of maximum 8 bytes
  218. ipu32, // unsigned Leb of maximum 4 bytes
  219. ipu64, // unsigned Leb of maximum 8 bytes
  220. ipf32, // float point single
  221. ipf64, // float point double
  222. ipJumpVec, // an array of jump labels used for br_table only
  223. ipResType, // result type used for blocks, such as If, block or loop
  224. ipCallType, // used for call_indirect
  225. ipi32OrFunc, // use for i32.const. Either a numeric OR function id is accepted.
  226. // numeric is used as an actually value.
  227. // function Id will be replaced with a reference number to the function
  228. // and relocation information would be generated
  229. ipZero // followed by a single byte zero
  230. );
  231. TInstFlag = record
  232. valid : Boolean;
  233. Param : TInstParamType;
  234. align : Byte; // used for memory operations only
  235. end;
  236. const
  237. INST_FLAGS : array [MIN_INST..MAX_INST] of TInstFlag = (
  238. (valid: true; Param: ipNone; align: 0) // 00 trap (unreachable)
  239. ,(valid: true; Param: ipNone; align: 0) // 01 nop
  240. ,(valid: true; Param: ipResType; align: 0) // 02 block
  241. ,(valid: true; Param: ipResType; align: 0) // 03 lock
  242. ,(valid: true; Param: ipResType; align: 0) // 04 if
  243. ,(valid: true; Param: ipNone; align: 0) // 05 else
  244. ,(valid: false; Param: ipNone; align: 0) // 06
  245. ,(valid: false; Param: ipNone; align: 0) // 07
  246. ,(valid: false; Param: ipNone; align: 0) // 08
  247. ,(valid: false; Param: ipNone; align: 0) // 09
  248. ,(valid: false; Param: ipNone; align: 0) // 0A
  249. ,(valid: true; Param: ipNone; align: 0) // 0B end
  250. ,(valid: true; Param: ipLeb; align: 0) // 0C br
  251. ,(valid: true; Param: ipLeb; align: 0) // 0D br_if
  252. ,(valid: true; Param: ipJumpVec; align: 0) // 0E br_table
  253. ,(valid: true; Param: ipNone; align: 0) // 0F return
  254. ,(valid: true; Param: ipLeb; align: 0) // 10 call
  255. ,(valid: true; Param: ipCallType; align: 0) // 11 call_indirect
  256. ,(valid: false; Param: ipNone; align: 0) // 12
  257. ,(valid: false; Param: ipNone; align: 0) // 13
  258. ,(valid: false; Param: ipNone; align: 0) // 14
  259. ,(valid: false; Param: ipNone; align: 0) // 15
  260. ,(valid: false; Param: ipNone; align: 0) // 16
  261. ,(valid: false; Param: ipNone; align: 0) // 17
  262. ,(valid: false; Param: ipNone; align: 0) // 18
  263. ,(valid: false; Param: ipNone; align: 0) // 19
  264. ,(valid: true; Param: ipNone; align: 0) // 1A drop
  265. ,(valid: true; Param: ipNone; align: 0) // 1B select
  266. ,(valid: false; Param: ipNone; align: 0) // 1C
  267. ,(valid: false; Param: ipNone; align: 0) // 1D
  268. ,(valid: false; Param: ipNone; align: 0) // 1E
  269. ,(valid: false; Param: ipNone; align: 0) // 1F
  270. ,(valid: true; Param: ipLeb; align: 0) // 20 local.get
  271. ,(valid: true; Param: ipLeb; align: 0) // 21 local.set
  272. ,(valid: true; Param: ipLeb; align: 0) // 22 local.tee
  273. ,(valid: true; Param: ipLeb; align: 0) // 23 global.get
  274. ,(valid: true; Param: ipLeb; align: 0) // 24 global.set
  275. ,(valid: false; Param: ipNone; align: 0) // 25
  276. ,(valid: false; Param: ipNone; align: 0) // 26
  277. ,(valid: false; Param: ipNone; align: 0) // 27
  278. ,(valid: true; Param: ipOfsAlign; align: 2) // 28 i32.load
  279. ,(valid: true; Param: ipOfsAlign; align: 3) // 29 i64_load
  280. ,(valid: true; Param: ipOfsAlign; align: 2) // 2A f32_load
  281. ,(valid: true; Param: ipOfsAlign; align: 3) // 2B f64_load
  282. ,(valid: true; Param: ipOfsAlign; align: 0) // 2C i32_load8_s
  283. ,(valid: true; Param: ipOfsAlign; align: 0) // 2D i32_load8_u
  284. ,(valid: true; Param: ipOfsAlign; align: 1) // 2E i32_load16_s
  285. ,(valid: true; Param: ipOfsAlign; align: 1) // 2F i32_load16_u
  286. ,(valid: true; Param: ipOfsAlign; align: 0) // 30 i64_load8_s
  287. ,(valid: true; Param: ipOfsAlign; align: 0) // 31 i64_load8_u
  288. ,(valid: true; Param: ipOfsAlign; align: 1) // 32 i64_load16_s
  289. ,(valid: true; Param: ipOfsAlign; align: 1) // 33 i64_load16_u
  290. ,(valid: true; Param: ipOfsAlign; align: 2) // 34 i64.load32_s
  291. ,(valid: true; Param: ipOfsAlign; align: 2) // 35 i64.load32_u
  292. ,(valid: true; Param: ipOfsAlign; align: 2) // 36 i32_store
  293. ,(valid: true; Param: ipOfsAlign; align: 3) // 37 i64_store
  294. ,(valid: true; Param: ipOfsAlign; align: 2) // 38 f32_store
  295. ,(valid: true; Param: ipOfsAlign; align: 3) // 39 f64_store
  296. ,(valid: true; Param: ipOfsAlign; align: 0) // 3A i32_store8
  297. ,(valid: true; Param: ipOfsAlign; align: 1) // 3B i32_store16
  298. ,(valid: true; Param: ipOfsAlign; align: 0) // 3C i64_store8
  299. ,(valid: true; Param: ipOfsAlign; align: 1) // 3D i64_store16
  300. ,(valid: true; Param: ipOfsAlign; align: 2) // 3E i64_store32
  301. ,(valid: true; Param: ipZero; align: 0) // 3F memory_size
  302. ,(valid: true; Param: ipZero; align: 0) // 40 memory_grow
  303. ,(valid: true; Param: ipi32OrFunc; align: 0) // 41 i32_const
  304. ,(valid: true; Param: ipi64; align: 0) // 42 i64_const
  305. ,(valid: true; Param: ipf32; align: 0) // 43 f32_const
  306. ,(valid: true; Param: ipf64; align: 0) // 44 f64_const
  307. ,(valid: true; Param: ipNone; align: 0) // 45 i32_eqz
  308. ,(valid: true; Param: ipNone; align: 0) // 46 i32_eq
  309. ,(valid: true; Param: ipNone; align: 0) // 47 i32_ne
  310. ,(valid: true; Param: ipNone; align: 0) // 48 i32_lt_s
  311. ,(valid: true; Param: ipNone; align: 0) // 49 i32_lt_u
  312. ,(valid: true; Param: ipNone; align: 0) // 4A i32_gt_s
  313. ,(valid: true; Param: ipNone; align: 0) // 4B i32_gt_u
  314. ,(valid: true; Param: ipNone; align: 0) // 4C i32_le_s
  315. ,(valid: true; Param: ipNone; align: 0) // 4D i32_le_u
  316. ,(valid: true; Param: ipNone; align: 0) // 4E i32_ge_s
  317. ,(valid: true; Param: ipNone; align: 0) // 4F i32_ge_u
  318. ,(valid: true; Param: ipNone; align: 0) // 50 i64_eqz
  319. ,(valid: true; Param: ipNone; align: 0) // 51 i64_eq
  320. ,(valid: true; Param: ipNone; align: 0) // 52 i64_ne
  321. ,(valid: true; Param: ipNone; align: 0) // 53 i64_lt_s
  322. ,(valid: true; Param: ipNone; align: 0) // 54 i64_lt_u
  323. ,(valid: true; Param: ipNone; align: 0) // 55 i64_gt_s
  324. ,(valid: true; Param: ipNone; align: 0) // 56 i64_gt_u
  325. ,(valid: true; Param: ipNone; align: 0) // 57 i64_le_s
  326. ,(valid: true; Param: ipNone; align: 0) // 58 i64_le_u
  327. ,(valid: true; Param: ipNone; align: 0) // 59 i64_ge_s
  328. ,(valid: true; Param: ipNone; align: 0) // 5A i64_ge_u
  329. ,(valid: true; Param: ipNone; align: 0) // 5B f32_eq
  330. ,(valid: true; Param: ipNone; align: 0) // 5C f32_ne
  331. ,(valid: true; Param: ipNone; align: 0) // 5D f32_lt
  332. ,(valid: true; Param: ipNone; align: 0) // 5E f32_gt
  333. ,(valid: true; Param: ipNone; align: 0) // 5F f32_le
  334. ,(valid: true; Param: ipNone; align: 0) // 60 f32_ge
  335. ,(valid: true; Param: ipNone; align: 0) // 61 f64_eq
  336. ,(valid: true; Param: ipNone; align: 0) // 62 f64_ne
  337. ,(valid: true; Param: ipNone; align: 0) // 63 f64_lt
  338. ,(valid: true; Param: ipNone; align: 0) // 64 f64_gt
  339. ,(valid: true; Param: ipNone; align: 0) // 65 f64_le
  340. ,(valid: true; Param: ipNone; align: 0) // 66 f64_ge
  341. ,(valid: true; Param: ipNone; align: 0) // 67 i32_clz
  342. ,(valid: true; Param: ipNone; align: 0) // 68 i32_ctz
  343. ,(valid: true; Param: ipNone; align: 0) // 69 i32_popcnt
  344. ,(valid: true; Param: ipNone; align: 0) // 6A i32_add
  345. ,(valid: true; Param: ipNone; align: 0) // 6B i32_sub
  346. ,(valid: true; Param: ipNone; align: 0) // 6C i32_mul
  347. ,(valid: true; Param: ipNone; align: 0) // 6D i32_div_s
  348. ,(valid: true; Param: ipNone; align: 0) // 6E i32_div_u
  349. ,(valid: true; Param: ipNone; align: 0) // 6F i32_rem_s
  350. ,(valid: true; Param: ipNone; align: 0) // 70 i32_rem_u
  351. ,(valid: true; Param: ipNone; align: 0) // 71 i32_and
  352. ,(valid: true; Param: ipNone; align: 0) // 72 i32_or
  353. ,(valid: true; Param: ipNone; align: 0) // 73 i32_xor
  354. ,(valid: true; Param: ipNone; align: 0) // 74 i32_shl
  355. ,(valid: true; Param: ipNone; align: 0) // 75 i32_shr_s
  356. ,(valid: true; Param: ipNone; align: 0) // 76 i32_shr_u
  357. ,(valid: true; Param: ipNone; align: 0) // 77 i32_rotl
  358. ,(valid: true; Param: ipNone; align: 0) // 78 i32_rotr
  359. ,(valid: true; Param: ipNone; align: 0) // 79 i64_clz
  360. ,(valid: true; Param: ipNone; align: 0) // 7A i64_ctz
  361. ,(valid: true; Param: ipNone; align: 0) // 7B i64_popcnt
  362. ,(valid: true; Param: ipNone; align: 0) // 7C i64_add
  363. ,(valid: true; Param: ipNone; align: 0) // 7D i64_sub
  364. ,(valid: true; Param: ipNone; align: 0) // 7E i64_mul
  365. ,(valid: true; Param: ipNone; align: 0) // 7F i64_div_s
  366. ,(valid: true; Param: ipNone; align: 0) // 80 i64_div_u
  367. ,(valid: true; Param: ipNone; align: 0) // 81 i64_rem_s
  368. ,(valid: true; Param: ipNone; align: 0) // 82 i64_rem_u
  369. ,(valid: true; Param: ipNone; align: 0) // 83 i64_and
  370. ,(valid: true; Param: ipNone; align: 0) // 84 i64_or
  371. ,(valid: true; Param: ipNone; align: 0) // 85 i64_xor
  372. ,(valid: true; Param: ipNone; align: 0) // 86 i64_shl
  373. ,(valid: true; Param: ipNone; align: 0) // 87 i64_shr_s
  374. ,(valid: true; Param: ipNone; align: 0) // 88 i64_shr_u
  375. ,(valid: true; Param: ipNone; align: 0) // 89 i64_rotl
  376. ,(valid: true; Param: ipNone; align: 0) // 8A i64_rotr
  377. ,(valid: true; Param: ipNone; align: 0) // 8B f32_abs
  378. ,(valid: true; Param: ipNone; align: 0) // 8C f32_neg
  379. ,(valid: true; Param: ipNone; align: 0) // 8D f32_ceil
  380. ,(valid: true; Param: ipNone; align: 0) // 8E f32_floor
  381. ,(valid: true; Param: ipNone; align: 0) // 8F f32_trunc
  382. ,(valid: true; Param: ipNone; align: 0) // 90 f32_nearest
  383. ,(valid: true; Param: ipNone; align: 0) // 91 f32_sqrt
  384. ,(valid: true; Param: ipNone; align: 0) // 92 f32_add
  385. ,(valid: true; Param: ipNone; align: 0) // 93 f32_sub
  386. ,(valid: true; Param: ipNone; align: 0) // 94 f32_mul
  387. ,(valid: true; Param: ipNone; align: 0) // 95 f32_div
  388. ,(valid: true; Param: ipNone; align: 0) // 96 f32_min
  389. ,(valid: true; Param: ipNone; align: 0) // 97 f32_max
  390. ,(valid: true; Param: ipNone; align: 0) // 98 f32_copysign
  391. ,(valid: true; Param: ipNone; align: 0) // 99 f64_abs
  392. ,(valid: true; Param: ipNone; align: 0) // 9A f64_neg
  393. ,(valid: true; Param: ipNone; align: 0) // 9B f64_ceil
  394. ,(valid: true; Param: ipNone; align: 0) // 9C f64_floor
  395. ,(valid: true; Param: ipNone; align: 0) // 9D f64_trunc
  396. ,(valid: true; Param: ipNone; align: 0) // 9E f64_nearest
  397. ,(valid: true; Param: ipNone; align: 0) // 9F f64_sqrt
  398. ,(valid: true; Param: ipNone; align: 0) // A0 f64_add
  399. ,(valid: true; Param: ipNone; align: 0) // A1 f64_sub
  400. ,(valid: true; Param: ipNone; align: 0) // A2 f64_mul
  401. ,(valid: true; Param: ipNone; align: 0) // A3 f64_div
  402. ,(valid: true; Param: ipNone; align: 0) // A4 f64_min
  403. ,(valid: true; Param: ipNone; align: 0) // A5 f64_max
  404. ,(valid: true; Param: ipNone; align: 0) // A6 f64_copysign
  405. ,(valid: true; Param: ipNone; align: 0) // A7 i32_wrap_i64
  406. ,(valid: true; Param: ipNone; align: 0) // A8 i32_trunc_f32_s
  407. ,(valid: true; Param: ipNone; align: 0) // A9 i32_trunc_f32_u
  408. ,(valid: true; Param: ipNone; align: 0) // AA i32_trunc_f64_s
  409. ,(valid: true; Param: ipNone; align: 0) // AB i32_trunc_f64_u
  410. ,(valid: true; Param: ipNone; align: 0) // AC i64_extend_i32_s
  411. ,(valid: true; Param: ipNone; align: 0) // AD i64_extend_i32_u
  412. ,(valid: true; Param: ipNone; align: 0) // AE i64_trunc_f32_s
  413. ,(valid: true; Param: ipNone; align: 0) // AF i64_trunc_f32_u
  414. ,(valid: true; Param: ipNone; align: 0) // B0 i64_trunc_f64_s
  415. ,(valid: true; Param: ipNone; align: 0) // B1 i64_trunc_f64_u
  416. ,(valid: true; Param: ipNone; align: 0) // B2 f32_convert_i32_s
  417. ,(valid: true; Param: ipNone; align: 0) // B3 f32_convert_i32_u
  418. ,(valid: true; Param: ipNone; align: 0) // B4 f32_convert_i64_s
  419. ,(valid: true; Param: ipNone; align: 0) // B5 f32_convert_i64_u
  420. ,(valid: true; Param: ipNone; align: 0) // B6 f32_demote_f64
  421. ,(valid: true; Param: ipNone; align: 0) // B7 f64_convert_i32_s
  422. ,(valid: true; Param: ipNone; align: 0) // B8 f64_convert_i32_u
  423. ,(valid: true; Param: ipNone; align: 0) // B9 f64_convert_i64_s
  424. ,(valid: true; Param: ipNone; align: 0) // BA f64_convert_i64_u
  425. ,(valid: true; Param: ipNone; align: 0) // BB f64_promote_f32
  426. ,(valid: true; Param: ipNone; align: 0) // BC i32_reinterpret_f32
  427. ,(valid: true; Param: ipNone; align: 0) // BD i64_reinterpret_f64
  428. ,(valid: true; Param: ipNone; align: 0) // BE f32_reinterpret_i32
  429. ,(valid: true; Param: ipNone; align: 0) // BF f64_reinterpret_i64
  430. );
  431. function InstLen(st: TStream; endOfInst: Byte = INST_END): Integer;
  432. implementation
  433. function InstLen(st: TStream; endOfInst: Byte = INST_END): Integer;
  434. var
  435. cd : byte;
  436. ofs : int64;
  437. b : byte;
  438. sz : int64;
  439. begin
  440. ofs := st.Position;
  441. try
  442. sz:=st.Size;
  443. while ofs < sz do begin
  444. cd := st.ReadByte;
  445. if (cd > MAX_INST) then begin
  446. Result:=-1; // invalid code
  447. Exit;
  448. end;
  449. if cd = endOfInst then break;
  450. case INST_FLAGS[cd].Param of
  451. ipLeb:
  452. ReadU(st);
  453. ipOfsAlign: begin
  454. ReadU(st);
  455. ReadU(st);
  456. end;
  457. ipJumpVec: begin // not implemented :(
  458. Result:=-2;
  459. Exit;
  460. end;
  461. ipi32: ReadS(st, 32);
  462. ipi64: ReadS(st, 64);
  463. ipf32: st.Position:=st.Position+4;
  464. ipf64: st.Position:=st.Position+8;
  465. ipResType: begin
  466. // it's a block. must go into recursion
  467. b := st.ReadByte; // reading type
  468. if (cd=INST_IF) and (b <> VALTYPE_NONE) then begin
  469. InstLen(st, INST_ELSE);
  470. InstLen(st, INST_END);
  471. end else
  472. InstLen(st, INST_END)
  473. end;
  474. end;
  475. end;
  476. finally
  477. Result := st.Position - ofs;
  478. st.Position:=ofs;
  479. end;
  480. end;
  481. end.