quick and dirty pure lua webassembly interpreter
1local ops = {}
2
3local constants = require("constants")
4local intutil = require("intutil")
5
6function ops.select(a, b, c)
7 return (c ~= 0) and a or b
8end
9
10--[[ i64 ]]
11
12function ops.i64_eqz(a)
13 return (a == 0) and 1 or 0
14end
15
16function ops.i64_eq(a, b)
17 return (a == b) and 1 or 0
18end
19
20function ops.i64_ne(a, b)
21 return (a ~= b) and 1 or 0
22end
23
24function ops.i64_lt_s(a, b)
25 return (a < b) and 1 or 0
26end
27
28function ops.i64_gt_s(a, b)
29 return (a > b) and 1 or 0
30end
31
32function ops.i64_le_s(a, b)
33 return (a <= b) and 1 or 0
34end
35
36function ops.i64_ge_s(a, b)
37 return (a >= b) and 1 or 0
38end
39
40function ops.i64_clz(a)
41 if a == 0 then
42 return 64
43 end
44
45 local n = 0
46 if (a & 0xFFFFFFFF00000000) == 0 then
47 n = n + 32
48 a = a << 32
49 end
50 if (a & 0xFFFF000000000000) == 0 then
51 n = n + 16
52 a = a << 16
53 end
54 if (a & 0xFF00000000000000) == 0 then
55 n = n + 8
56 a = a << 8
57 end
58 if (a & 0xF000000000000000) == 0 then
59 n = n + 4
60 a = a << 4
61 end
62 if (a & 0xC000000000000000) == 0 then
63 n = n + 2
64 a = a << 2
65 end
66 if (a & 0x8000000000000000) == 0 then
67 n = n + 1
68 end
69 return n
70end
71
72function ops.i64_ctz(a)
73 if a == 0 then
74 return 64
75 end
76
77 local n = 0
78 if (a & 0x00000000FFFFFFFF) == 0 then
79 n = n + 32
80 a = a >> 32
81 end
82 if (a & 0x000000000000FFFF) == 0 then
83 n = n + 16
84 a = a >> 16
85 end
86 if (a & 0x00000000000000FF) == 0 then
87 n = n + 8
88 a = a >> 8
89 end
90 if (a & 0x000000000000000F) == 0 then
91 n = n + 4
92 a = a >> 4
93 end
94 if (a & 0x0000000000000003) == 0 then
95 n = n + 2
96 a = a >> 2
97 end
98 if (a & 0x0000000000000001) == 0 then
99 n = n + 1
100 end
101 return n
102end
103
104function ops.i64_popcnt(a)
105 local n = 0
106 for _ = 1, 64 do
107 if (a & 1) == 1 then
108 n = n + 1
109 end
110 a = a >> 1
111 end
112 return n
113end
114
115function ops.i64_add(a, b)
116 return a + b
117end
118
119function ops.i64_sub(a, b)
120 return a - b
121end
122
123function ops.i64_mul(a, b)
124 return a * b
125end
126
127function ops.i64_div_s(a, b)
128 return a // b
129end
130
131function ops.i64_rem_s(a, b)
132 return a % b
133end
134
135function ops.i64_and(a, b)
136 return a & b
137end
138
139function ops.i64_or(a, b)
140 return a | b
141end
142
143function ops.i64_xor(a, b)
144 return a ~ b
145end
146
147function ops.i64_shl(a, b)
148 return a << b
149end
150
151function ops.i64_shr_u(a, b)
152 return a >> b
153end
154
155function ops.i64_rotl(a, b)
156 local c = b % 64
157 return (a << c) | (a >> (64 - c))
158end
159
160function ops.i64_rotr(a, b)
161 local c = b % 64
162 return (a >> c) | (a << (64 - c))
163end
164
165--[[ i32 ]]
166
167function ops.i32_eqz(a)
168 return (a == 0) and 1 or 0
169end
170
171function ops.i32_eq(a, b)
172 return (a == b) and 1 or 0
173end
174
175function ops.i32_ne(a, b)
176 return (a ~= b) and 1 or 0
177end
178
179function ops.i32_lt_s(a, b)
180 a = intutil.signexti32(a)
181 b = intutil.signexti32(b)
182 return (a < b) and 1 or 0
183end
184
185function ops.i32_lt_s(a, b)
186 a = intutil.signexti32(a)
187 b = intutil.signexti32(b)
188 return (a < b) and 1 or 0
189end
190
191function ops.i32_lt_u(a, b)
192 return (a < b) and 1 or 0
193end
194
195function ops.i32_gt_s(a, b)
196 a = intutil.signexti32(a)
197 b = intutil.signexti32(b)
198 return (a > b) and 1 or 0
199end
200
201function ops.i32_gt_u(a, b)
202 return (a > b) and 1 or 0
203end
204
205function ops.i32_le_s(a, b)
206 a = intutil.signexti32(a)
207 b = intutil.signexti32(b)
208 return (a <= b) and 1 or 0
209end
210
211function ops.i32_le_u(a, b)
212 return (a <= b) and 1 or 0
213end
214
215function ops.i32_ge_s(a, b)
216 a = intutil.signexti32(a)
217 b = intutil.signexti32(b)
218 return (a >= b) and 1 or 0
219end
220
221function ops.i32_ge_u(a, b)
222 return (a >= b) and 1 or 0
223end
224
225function ops.i32_clz(a)
226 if a == 0 then
227 return 32
228 end
229
230 local n = 0
231 if (a & 0xFFFF0000) == 0 then
232 n = n + 16
233 a = a << 16
234 end
235 if (a & 0xFF000000) == 0 then
236 n = n + 8
237 a = a << 8
238 end
239 if (a & 0xF0000000) == 0 then
240 n = n + 4
241 a = a << 4
242 end
243 if (a & 0xC0000000) == 0 then
244 n = n + 2
245 a = a << 2
246 end
247 if (a & 0x80000000) == 0 then
248 n = n + 1
249 end
250 return n
251end
252
253function ops.i32_ctz(a)
254 if a == 0 then
255 return 64
256 end
257
258 local n = 0
259 if (a & 0x0000FFFF) == 0 then
260 n = n + 16
261 a = a >> 16
262 end
263 if (a & 0x000000FF) == 0 then
264 n = n + 8
265 a = a >> 8
266 end
267 if (a & 0x0000000F) == 0 then
268 n = n + 4
269 a = a >> 4
270 end
271 if (a & 0x00000003) == 0 then
272 n = n + 2
273 a = a >> 2
274 end
275 if (a & 0x00000001) == 0 then
276 n = n + 1
277 end
278 return n
279end
280
281function ops.i32_popcnt(a)
282 local n = 0
283 for _ = 1, 32 do
284 if (a & 1) == 1 then
285 n = n + 1
286 end
287 a = a >> 1
288 end
289 return n
290end
291
292function ops.i32_add(a, b)
293 return (a + b) & constants.I32_MAX
294end
295
296function ops.i32_sub(a, b)
297 return (a - b) & constants.I32_MAX
298end
299
300function ops.i32_mul(a, b)
301 return (a * b) & constants.I32_MAX
302end
303
304function ops.i32_div_s(a, b)
305 a = intutil.signexti32(a)
306 b = intutil.signexti32(b)
307 return (a // b) & constants.I32_MAX
308end
309
310function ops.i32_div_u(a, b)
311 return (a // b) & constants.I32_MAX
312end
313
314function ops.i32_rem_s(a, b)
315 a = intutil.signexti32(a)
316 b = intutil.signexti32(b)
317 return (a % b) & constants.I32_MAX
318end
319
320function ops.i32_rem_u(a, b)
321 return (a % b) & constants.I32_MAX
322end
323
324function ops.i32_and(a, b)
325 return a & b
326end
327
328function ops.i32_or(a, b)
329 return a | b
330end
331
332function ops.i32_xor(a, b)
333 return a ~ b
334end
335
336function ops.i32_shl(a, b)
337 return (a << b) & constants.I32_MAX
338end
339
340function ops.i32_shr_u(a, b)
341 return (a >> b) & constants.I32_MAX
342end
343
344function ops.i32_shr_s(a, b)
345 if b >= 32 then
346 if (a & 0x80000000) == 0 then
347 return 0
348 else
349 return constants.I32_MAX
350 end
351 end
352
353 local result = a >> b
354 if (a & 0x80000000) ~= 0 then
355 result = result | (((1 << b) - 1) << (32 - b))
356 end
357 return result
358end
359
360function ops.i32_rotl(a, b)
361 local c = b % 32
362 return ((a << c) | (a >> (32 - c))) & constants.I32_MAX
363end
364
365function ops.i32_rotr(a, b)
366 local c = b % 32
367 return ((a >> c) | (a << (32 - c))) & constants.I32_MAX
368end
369
370--[[ int conversions ]]
371
372function ops.i32_wrap_i64(a)
373 return a & constants.I32_MAX
374end
375
376function ops.i64_extend_i32_s(a)
377 return intutil.signexti32(a)
378end
379
380function ops.i64_extend_i32_u(a)
381 return a
382end
383
384function ops.i32_extend8_s(a)
385 return intutil.signexti8(a) & constants.I32_MAX
386end
387
388function ops.i32_extend16_s(a)
389 return intutil.signexti16(a) & constants.I32_MAX
390end
391
392function ops.i64_extend8_s(a)
393 return intutil.signexti8(a)
394end
395
396function ops.i64_extend16_s(a)
397 return intutil.signexti16(a)
398end
399
400function ops.i64_extend32_s(a)
401 return intutil.signexti32(a)
402end
403
404return ops