wardite 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,250 @@
1
+ # rbs_inline: enabled
2
+ require_relative "value"
3
+
4
+ module Wardite
5
+ module Evaluator
6
+ # @rbs runtime: Runtime
7
+ # @rbs frame: Frame
8
+ # @rbs insn: Op
9
+ # @rbs return: void
10
+ def self.f64_eval_insn(runtime, frame, insn)
11
+ case insn.code
12
+
13
+ when :f64_load
14
+ _align = insn.operand[0] # TODO: alignment support?
15
+ offset = insn.operand[1]
16
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
17
+
18
+ addr = runtime.stack.pop
19
+ if !addr.is_a?(I32)
20
+ raise EvalError, "maybe stack too short"
21
+ end
22
+
23
+ at = addr.value + offset
24
+ data_end = at + F64.new.memsize / 8
25
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
26
+ buf = memory.data[at...data_end]
27
+ if !buf
28
+ raise EvalError, "invalid memory range"
29
+ end
30
+ runtime.stack.push(F64.from_bytes(buf))
31
+
32
+
33
+ when :f64_store
34
+ _align = insn.operand[0] # TODO: alignment support?
35
+ offset = insn.operand[1]
36
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
37
+
38
+ value = runtime.stack.pop
39
+ addr = runtime.stack.pop
40
+ if !value.is_a?(F64) || !addr.is_a?(I32)
41
+ raise EvalError, "maybe stack too short"
42
+ end
43
+
44
+ at = addr.value + offset
45
+ data_end = at + value.packed.size
46
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
47
+ memory.data[at...data_end] = value.packed
48
+
49
+
50
+ when :f64_const
51
+ const = insn.operand[0]
52
+ if !const.is_a?(Float)
53
+ raise EvalError, "invalid type of operand"
54
+ end
55
+ runtime.stack.push(F64(const))
56
+
57
+
58
+ when :f64_eqz
59
+ target = runtime.stack.pop
60
+ if !target.is_a?(F64)
61
+ raise EvalError, "maybe empty or invalid stack"
62
+ end
63
+ value = target.value.zero? ? 1 : 0
64
+ runtime.stack.push(I32(value))
65
+
66
+
67
+ when :f64_eq
68
+ right, left = runtime.stack.pop, runtime.stack.pop
69
+ if !right.is_a?(F64) || !left.is_a?(F64)
70
+ raise EvalError, "maybe empty or invalid stack"
71
+ end
72
+ value = (left.value == right.value) ? 1 : 0
73
+ runtime.stack.push(I32(value))
74
+
75
+
76
+ when :f64_ne
77
+ right, left = runtime.stack.pop, runtime.stack.pop
78
+ if !right.is_a?(F64) || !left.is_a?(F64)
79
+ raise EvalError, "maybe empty or invalid stack"
80
+ end
81
+ value = (left.value != right.value) ? 1 : 0
82
+ runtime.stack.push(I32(value))
83
+
84
+
85
+ when :f64_lt
86
+ right, left = runtime.stack.pop, runtime.stack.pop
87
+ if !right.is_a?(F64) || !left.is_a?(F64)
88
+ raise EvalError, "maybe empty or invalid stack"
89
+ end
90
+ value = (left.value < right.value) ? 1 : 0
91
+ runtime.stack.push(I32(value))
92
+
93
+
94
+ when :f64_gt
95
+ right, left = runtime.stack.pop, runtime.stack.pop
96
+ if !right.is_a?(F64) || !left.is_a?(F64)
97
+ raise EvalError, "maybe empty or invalid stack"
98
+ end
99
+ value = (left.value > right.value) ? 1 : 0
100
+ runtime.stack.push(I32(value))
101
+
102
+
103
+ when :f64_le
104
+ right, left = runtime.stack.pop, runtime.stack.pop
105
+ if !right.is_a?(F64) || !left.is_a?(F64)
106
+ raise EvalError, "maybe empty or invalid stack"
107
+ end
108
+ value = (left.value <= right.value) ? 1 : 0
109
+ runtime.stack.push(I32(value))
110
+
111
+
112
+ when :f64_ge
113
+ right, left = runtime.stack.pop, runtime.stack.pop
114
+ if !right.is_a?(F64) || !left.is_a?(F64)
115
+ raise EvalError, "maybe empty or invalid stack"
116
+ end
117
+ value = (left.value >= right.value) ? 1 : 0
118
+ runtime.stack.push(I32(value))
119
+
120
+
121
+ when :f64_abs
122
+ x = runtime.stack.pop
123
+ if !x.is_a?(F64)
124
+ raise EvalError, "maybe empty or invalid stack"
125
+ end
126
+ runtime.stack.push(F64(x.value.abs))
127
+
128
+
129
+ when :f64_neg
130
+ x = runtime.stack.pop
131
+ if !x.is_a?(F64)
132
+ raise EvalError, "maybe empty or invalid stack"
133
+ end
134
+ runtime.stack.push(F64(-(x.value)))
135
+
136
+
137
+ when :f64_ceil
138
+ x = runtime.stack.pop
139
+ if !x.is_a?(F64)
140
+ raise EvalError, "maybe empty or invalid stack"
141
+ end
142
+ runtime.stack.push(F64(x.value.ceil.to_f))
143
+
144
+
145
+ when :f64_floor
146
+ x = runtime.stack.pop
147
+ if !x.is_a?(F64)
148
+ raise EvalError, "maybe empty or invalid stack"
149
+ end
150
+ runtime.stack.push(F64(x.value.floor.to_f))
151
+
152
+
153
+ when :f64_trunc
154
+ x = runtime.stack.pop
155
+ if !x.is_a?(F64)
156
+ raise EvalError, "maybe empty or invalid stack"
157
+ end
158
+ runtime.stack.push(F64(x.value.to_i.to_f))
159
+
160
+
161
+ when :f64_nearest
162
+ x = runtime.stack.pop
163
+ if !x.is_a?(F64)
164
+ raise EvalError, "maybe empty or invalid stack"
165
+ end
166
+ runtime.stack.push(F64(x.value.round.to_f))
167
+
168
+
169
+ when :f64_sqrt
170
+ x = runtime.stack.pop
171
+ if !x.is_a?(F64)
172
+ raise EvalError, "maybe empty or invalid stack"
173
+ end
174
+ runtime.stack.push(F64(x.value ** 0.5))
175
+
176
+
177
+ when :f64_add
178
+ right, left = runtime.stack.pop, runtime.stack.pop
179
+ if !right.is_a?(F64) || !left.is_a?(F64)
180
+ raise EvalError, "maybe empty or invalid stack"
181
+ end
182
+ runtime.stack.push(F64(left.value + right.value))
183
+
184
+
185
+ when :f64_sub
186
+ right, left = runtime.stack.pop, runtime.stack.pop
187
+ if !right.is_a?(F64) || !left.is_a?(F64)
188
+ raise EvalError, "maybe empty or invalid stack"
189
+ end
190
+ runtime.stack.push(F64(left.value - right.value))
191
+
192
+
193
+ when :f64_mul
194
+ right, left = runtime.stack.pop, runtime.stack.pop
195
+ if !right.is_a?(F64) || !left.is_a?(F64)
196
+ raise EvalError, "maybe empty or invalid stack"
197
+ end
198
+ runtime.stack.push(F64(left.value * right.value))
199
+
200
+
201
+ when :f64_div
202
+ right, left = runtime.stack.pop, runtime.stack.pop
203
+ if !right.is_a?(F64) || !left.is_a?(F64)
204
+ raise EvalError, "maybe empty or invalid stack"
205
+ end
206
+ runtime.stack.push(F64(left.value / right.value))
207
+
208
+
209
+ when :f64_min
210
+ right, left = runtime.stack.pop, runtime.stack.pop
211
+ if !right.is_a?(F64) || !left.is_a?(F64)
212
+ raise EvalError, "maybe empty or invalid stack"
213
+ end
214
+ if right.value.nan? || left.value.nan?
215
+ runtime.stack.push(F64(Float::NAN))
216
+ return
217
+ end
218
+ runtime.stack.push(F64([left.value, right.value].min))
219
+
220
+
221
+ when :f64_max
222
+ right, left = runtime.stack.pop, runtime.stack.pop
223
+ if !right.is_a?(F64) || !left.is_a?(F64)
224
+ raise EvalError, "maybe empty or invalid stack"
225
+ end
226
+ if right.value.nan? || left.value.nan?
227
+ runtime.stack.push(F64(Float::NAN))
228
+ return
229
+ end
230
+ runtime.stack.push(F64([left.value, right.value].max))
231
+
232
+
233
+ when :f64_copysign
234
+ right, left = runtime.stack.pop, runtime.stack.pop
235
+ if !right.is_a?(F64) || !left.is_a?(F64)
236
+ raise EvalError, "maybe empty or invalid stack"
237
+ end
238
+ if left.sign == right.sign
239
+ runtime.stack.push(F64(left.value))
240
+ else
241
+ runtime.stack.push(F64(-left.value))
242
+ end
243
+
244
+
245
+ else
246
+ raise "Unknown opcode for namespace #{insn.namespace}: #{insn.code}"
247
+ end
248
+ end
249
+ end
250
+ end
@@ -10,7 +10,202 @@ module Wardite
10
10
  def self.i32_eval_insn(runtime, frame, insn)
11
11
  case insn.code
12
12
 
13
+ when :i32_load
14
+ _align = insn.operand[0] # TODO: alignment support?
15
+ offset = insn.operand[1]
16
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
17
+
18
+ addr = runtime.stack.pop
19
+ if !addr.is_a?(I32)
20
+ raise EvalError, "maybe stack too short"
21
+ end
22
+
23
+ at = addr.value + offset
24
+ data_end = at + I32.new.memsize / 8
25
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
26
+ buf = memory.data[at...data_end]
27
+ if !buf
28
+ raise EvalError, "invalid memory range"
29
+ end
30
+ runtime.stack.push(I32.from_bytes(buf))
31
+
32
+
33
+ when :i32_load8_s
34
+ _align = insn.operand[0] # TODO: alignment support?
35
+ offset = insn.operand[1]
36
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
37
+
38
+ addr = runtime.stack.pop
39
+ if !addr.is_a?(I32)
40
+ raise EvalError, "maybe stack too short"
41
+ end
42
+
43
+ at = addr.value + offset
44
+ data_end = at + 1
45
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
46
+ buf = memory.data[at...data_end]
47
+ if !buf
48
+ raise EvalError, "invalid memory range"
49
+ end
50
+ runtime.stack.push(I32.from_bytes(buf, size: 8, signed: true))
51
+
52
+
53
+ when :i32_load8_u
54
+ _align = insn.operand[0] # TODO: alignment support?
55
+ offset = insn.operand[1]
56
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
57
+
58
+ addr = runtime.stack.pop
59
+ if !addr.is_a?(I32)
60
+ raise EvalError, "maybe stack too short"
61
+ end
62
+
63
+ at = addr.value + offset
64
+ data_end = at + 1
65
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
66
+ buf = memory.data[at...data_end]
67
+ if !buf
68
+ raise EvalError, "invalid memory range"
69
+ end
70
+ runtime.stack.push(I32.from_bytes(buf, size: 8, signed: false))
71
+
72
+
73
+ when :i32_load16_s
74
+ _align = insn.operand[0] # TODO: alignment support?
75
+ offset = insn.operand[1]
76
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
77
+
78
+ addr = runtime.stack.pop
79
+ if !addr.is_a?(I32)
80
+ raise EvalError, "maybe stack too short"
81
+ end
82
+
83
+ at = addr.value + offset
84
+ data_end = at + 2
85
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
86
+ buf = memory.data[at...data_end]
87
+ if !buf
88
+ raise EvalError, "invalid memory range"
89
+ end
90
+ runtime.stack.push(I32.from_bytes(buf, size: 16, signed: true))
91
+
92
+
93
+ when :i32_load16_u
94
+ _align = insn.operand[0] # TODO: alignment support?
95
+ offset = insn.operand[1]
96
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
97
+
98
+ addr = runtime.stack.pop
99
+ if !addr.is_a?(I32)
100
+ raise EvalError, "maybe stack too short"
101
+ end
102
+
103
+ at = addr.value + offset
104
+ data_end = at + 2
105
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
106
+ buf = memory.data[at...data_end]
107
+ if !buf
108
+ raise EvalError, "invalid memory range"
109
+ end
110
+ runtime.stack.push(I32.from_bytes(buf, size: 16, signed: false))
111
+
112
+
113
+ when :i32_store
114
+ _align = insn.operand[0] # TODO: alignment support?
115
+ offset = insn.operand[1]
116
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
117
+
118
+ value = runtime.stack.pop
119
+ addr = runtime.stack.pop
120
+ if !value.is_a?(I32) || !addr.is_a?(I32)
121
+ raise EvalError, "maybe stack too short"
122
+ end
123
+
124
+ at = addr.value + offset
125
+ data_end = at + value.packed.size
126
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
127
+ memory.data[at...data_end] = value.packed
128
+
129
+
130
+ when :i32_store8
131
+ _align = insn.operand[0] # TODO: alignment support?
132
+ offset = insn.operand[1]
133
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
134
+
135
+ value = runtime.stack.pop
136
+ addr = runtime.stack.pop
137
+ if !value.is_a?(I32) || !addr.is_a?(I32)
138
+ raise EvalError, "maybe stack too short"
139
+ end
140
+
141
+ at = addr.value + offset
142
+ data_end = at + 1
143
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
144
+ memory.data[at...data_end] = value.packed(size: 8)
145
+
146
+
147
+ when :i32_store16
148
+ _align = insn.operand[0] # TODO: alignment support?
149
+ offset = insn.operand[1]
150
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
151
+
152
+ value = runtime.stack.pop
153
+ addr = runtime.stack.pop
154
+ if !value.is_a?(I32) || !addr.is_a?(I32)
155
+ raise EvalError, "maybe stack too short"
156
+ end
157
+
158
+ at = addr.value + offset
159
+ data_end = at + 2
160
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
161
+ memory.data[at...data_end] = value.packed(size: 16)
162
+
163
+
164
+ when :i32_const
165
+ const = insn.operand[0]
166
+ if !const.is_a?(Integer)
167
+ raise EvalError, "invalid type of operand"
168
+ end
169
+ runtime.stack.push(I32(const))
170
+
171
+
172
+ when :i32_eqz
173
+ target = runtime.stack.pop
174
+ if !target.is_a?(I32)
175
+ raise EvalError, "maybe empty or invalid stack"
176
+ end
177
+ value = target.value.zero? ? 1 : 0
178
+ runtime.stack.push(I32(value))
179
+
180
+
181
+ when :i32_eq
182
+ right, left = runtime.stack.pop, runtime.stack.pop
183
+ if !right.is_a?(I32) || !left.is_a?(I32)
184
+ raise EvalError, "maybe empty or invalid stack"
185
+ end
186
+ value = (left.value == right.value) ? 1 : 0
187
+ runtime.stack.push(I32(value))
188
+
189
+
190
+ when :i32_ne
191
+ right, left = runtime.stack.pop, runtime.stack.pop
192
+ if !right.is_a?(I32) || !left.is_a?(I32)
193
+ raise EvalError, "maybe empty or invalid stack"
194
+ end
195
+ value = (left.value != right.value) ? 1 : 0
196
+ runtime.stack.push(I32(value))
197
+
198
+
13
199
  when :i32_lts
200
+ right, left = runtime.stack.pop, runtime.stack.pop
201
+ if !right.is_a?(I32) || !left.is_a?(I32)
202
+ raise EvalError, "maybe empty or invalid stack"
203
+ end
204
+ value = (left.value_s < right.value_s) ? 1 : 0
205
+ runtime.stack.push(I32(value))
206
+
207
+
208
+ when :i32_ltu
14
209
  right, left = runtime.stack.pop, runtime.stack.pop
15
210
  if !right.is_a?(I32) || !left.is_a?(I32)
16
211
  raise EvalError, "maybe empty or invalid stack"
@@ -19,7 +214,52 @@ module Wardite
19
214
  runtime.stack.push(I32(value))
20
215
 
21
216
 
217
+ when :i32_gts
218
+ right, left = runtime.stack.pop, runtime.stack.pop
219
+ if !right.is_a?(I32) || !left.is_a?(I32)
220
+ raise EvalError, "maybe empty or invalid stack"
221
+ end
222
+ value = (left.value_s > right.value_s) ? 1 : 0
223
+ runtime.stack.push(I32(value))
224
+
225
+
226
+ when :i32_gtu
227
+ right, left = runtime.stack.pop, runtime.stack.pop
228
+ if !right.is_a?(I32) || !left.is_a?(I32)
229
+ raise EvalError, "maybe empty or invalid stack"
230
+ end
231
+ value = (left.value > right.value) ? 1 : 0
232
+ runtime.stack.push(I32(value))
233
+
234
+
235
+ when :i32_les
236
+ right, left = runtime.stack.pop, runtime.stack.pop
237
+ if !right.is_a?(I32) || !left.is_a?(I32)
238
+ raise EvalError, "maybe empty or invalid stack"
239
+ end
240
+ value = (left.value_s <= right.value_s) ? 1 : 0
241
+ runtime.stack.push(I32(value))
242
+
243
+
22
244
  when :i32_leu
245
+ right, left = runtime.stack.pop, runtime.stack.pop
246
+ if !right.is_a?(I32) || !left.is_a?(I32)
247
+ raise EvalError, "maybe empty or invalid stack"
248
+ end
249
+ value = (left.value <= right.value) ? 1 : 0
250
+ runtime.stack.push(I32(value))
251
+
252
+
253
+ when :i32_ges
254
+ right, left = runtime.stack.pop, runtime.stack.pop
255
+ if !right.is_a?(I32) || !left.is_a?(I32)
256
+ raise EvalError, "maybe empty or invalid stack"
257
+ end
258
+ value = (left.value_s >= right.value_s) ? 1 : 0
259
+ runtime.stack.push(I32(value))
260
+
261
+
262
+ when :i32_geu
23
263
  right, left = runtime.stack.pop, runtime.stack.pop
24
264
  if !right.is_a?(I32) || !left.is_a?(I32)
25
265
  raise EvalError, "maybe empty or invalid stack"
@@ -28,6 +268,56 @@ module Wardite
28
268
  runtime.stack.push(I32(value))
29
269
 
30
270
 
271
+ when :i32_clz
272
+ target = runtime.stack.pop
273
+ if !target.is_a?(I32)
274
+ raise EvalError, "maybe empty or invalid stack"
275
+ end
276
+ start = target.memsize - 1
277
+ count = 0
278
+ while start > -1
279
+ if (target.value >> start).zero?
280
+ count += 1
281
+ start -= 1
282
+ else
283
+ break
284
+ end
285
+ end
286
+ runtime.stack.push(I32(count))
287
+
288
+
289
+ when :i32_ctz
290
+ target = runtime.stack.pop
291
+ if !target.is_a?(I32)
292
+ raise EvalError, "maybe empty or invalid stack"
293
+ end
294
+ finish = target.memsize
295
+ count = 0
296
+ while count < finish
297
+ if (target.value & (1 << count)).zero?
298
+ count += 1
299
+ else
300
+ break
301
+ end
302
+ end
303
+ runtime.stack.push(I32(count))
304
+
305
+
306
+ when :i32_popcnt
307
+ target = runtime.stack.pop
308
+ if !target.is_a?(I32)
309
+ raise EvalError, "maybe empty or invalid stack"
310
+ end
311
+ digits = target.memsize
312
+ count = 0
313
+ digits.times do |i|
314
+ if (target.value & (1 << i)).zero?
315
+ count += 1
316
+ end
317
+ end
318
+ runtime.stack.push(I32(count))
319
+
320
+
31
321
  when :i32_add
32
322
  right, left = runtime.stack.pop, runtime.stack.pop
33
323
  if !right.is_a?(I32) || !left.is_a?(I32)
@@ -44,29 +334,119 @@ module Wardite
44
334
  runtime.stack.push(I32(left.value - right.value))
45
335
 
46
336
 
47
- when :i32_const
48
- const = insn.operand[0]
49
- if !const.is_a?(Integer)
50
- raise EvalError, "invalid type of operand"
337
+ when :i32_mul
338
+ right, left = runtime.stack.pop, runtime.stack.pop
339
+ if !right.is_a?(I32) || !left.is_a?(I32)
340
+ raise EvalError, "maybe empty or invalid stack"
51
341
  end
52
- runtime.stack.push(I32(const))
342
+ runtime.stack.push(I32(left.value * right.value))
53
343
 
54
344
 
55
- when :i32_store
56
- _align = insn.operand[0] # TODO: alignment support?
57
- offset = insn.operand[1]
58
- raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
59
-
60
- value = runtime.stack.pop
61
- addr = runtime.stack.pop
62
- if !value.is_a?(I32) || !addr.is_a?(I32)
63
- raise EvalError, "maybe stack too short"
345
+ when :i32_div_s
346
+ right, left = runtime.stack.pop, runtime.stack.pop
347
+ if !right.is_a?(I32) || !left.is_a?(I32)
348
+ raise EvalError, "maybe empty or invalid stack"
349
+ end
350
+ runtime.stack.push(I32(left.value_s / right.value_s))
351
+
352
+
353
+ when :i32_div_u
354
+ right, left = runtime.stack.pop, runtime.stack.pop
355
+ if !right.is_a?(I32) || !left.is_a?(I32)
356
+ raise EvalError, "maybe empty or invalid stack"
357
+ end
358
+ runtime.stack.push(I32(left.value / right.value))
359
+
360
+
361
+ when :i32_rem_s
362
+ right, left = runtime.stack.pop, runtime.stack.pop
363
+ if !right.is_a?(I32) || !left.is_a?(I32)
364
+ raise EvalError, "maybe empty or invalid stack"
365
+ end
366
+ runtime.stack.push(I32(left.value_s % right.value_s))
367
+
368
+
369
+ when :i32_rem_u
370
+ right, left = runtime.stack.pop, runtime.stack.pop
371
+ if !right.is_a?(I32) || !left.is_a?(I32)
372
+ raise EvalError, "maybe empty or invalid stack"
373
+ end
374
+ runtime.stack.push(I32(left.value % right.value))
375
+
376
+
377
+ when :i32_and
378
+ right, left = runtime.stack.pop, runtime.stack.pop
379
+ if !right.is_a?(I32) || !left.is_a?(I32)
380
+ raise EvalError, "maybe empty or invalid stack"
381
+ end
382
+ runtime.stack.push(I32(left.value & right.value))
383
+
384
+
385
+ when :i32_or
386
+ right, left = runtime.stack.pop, runtime.stack.pop
387
+ if !right.is_a?(I32) || !left.is_a?(I32)
388
+ raise EvalError, "maybe empty or invalid stack"
389
+ end
390
+ runtime.stack.push(I32(left.value | right.value))
391
+
392
+
393
+ when :i32_xor
394
+ right, left = runtime.stack.pop, runtime.stack.pop
395
+ if !right.is_a?(I32) || !left.is_a?(I32)
396
+ raise EvalError, "maybe empty or invalid stack"
397
+ end
398
+ runtime.stack.push(I32(left.value ^ right.value))
399
+
400
+
401
+ when :i32_shl
402
+ right, left = runtime.stack.pop, runtime.stack.pop
403
+ if !right.is_a?(I32) || !left.is_a?(I32)
404
+ raise EvalError, "maybe empty or invalid stack"
64
405
  end
406
+ value = left.value << right.value
407
+ value %= (1 << right.memsize)
65
408
 
66
- at = addr.value + offset
67
- data_end = at + value.packed.size
68
- memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
69
- memory.data[at...data_end] = value.packed
409
+ runtime.stack.push(I32(value))
410
+
411
+
412
+ when :i32_shr_s
413
+ right, left = runtime.stack.pop, runtime.stack.pop
414
+ if !right.is_a?(I32) || !left.is_a?(I32)
415
+ raise EvalError, "maybe empty or invalid stack"
416
+ end
417
+ value = left.value_s >> right.value
418
+ runtime.stack.push(I32(value))
419
+
420
+
421
+ when :i32_shr_u
422
+ right, left = runtime.stack.pop, runtime.stack.pop
423
+ if !right.is_a?(I32) || !left.is_a?(I32)
424
+ raise EvalError, "maybe empty or invalid stack"
425
+ end
426
+ value = left.value >> right.value
427
+ runtime.stack.push(I32(value))
428
+
429
+
430
+ when :i32_rotl
431
+ right, left = runtime.stack.pop, runtime.stack.pop
432
+ if !right.is_a?(I32) || !left.is_a?(I32)
433
+ raise EvalError, "maybe empty or invalid stack"
434
+ end
435
+ rotated = left.value << right.value
436
+ rest = left.value & (I32::I32_MAX << (right.memsize - right.value))
437
+ value = rotated | (rest >> (right.memsize - right.value))
438
+ runtime.stack.push(I32(value))
439
+
440
+
441
+ when :i32_rotr
442
+ right, left = runtime.stack.pop, runtime.stack.pop
443
+ if !right.is_a?(I32) || !left.is_a?(I32)
444
+ raise EvalError, "maybe empty or invalid stack"
445
+ end
446
+ rotated = left.value >> right.value
447
+ rest = left.value & (I32::I32_MAX >> (right.memsize - right.value))
448
+ value = rotated | (rest << (right.memsize - right.value))
449
+ runtime.stack.push(I32(value))
70
450
 
71
451
 
72
452
  else