wardite 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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