wardite 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/Rakefile +163 -0
- data/Steepfile +1 -0
- data/examples/consts.wat +12 -0
- data/lib/wardite/alu_f32.generated.rb +250 -0
- data/lib/wardite/alu_f64.generated.rb +250 -0
- data/lib/wardite/alu_i32.generated.rb +398 -18
- data/lib/wardite/alu_i64.generated.rb +514 -0
- data/lib/wardite/convert.generated.rb +234 -0
- data/lib/wardite/instruction.rb +62 -31
- data/lib/wardite/value.rb +576 -31
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite/wasi.rb +1 -1
- data/lib/wardite.rb +127 -77
- data/scripts/gen_alu.rb +653 -27
- data/scripts/gen_conv.rb +76 -0
- data/scripts/templates/conv_module.rb.tmpl +18 -0
- data/sig/generated/wardite/alu_f32.generated.rbs +11 -0
- data/sig/generated/wardite/alu_f64.generated.rbs +11 -0
- data/sig/generated/wardite/alu_i64.generated.rbs +11 -0
- data/sig/generated/wardite/convert.generated.rbs +11 -0
- data/sig/generated/wardite/instruction.rbs +6 -0
- data/sig/generated/wardite/value.rbs +263 -19
- data/sig/generated/wardite.rbs +12 -3
- metadata +13 -2
data/lib/wardite/value.rb
CHANGED
@@ -1,39 +1,479 @@
|
|
1
1
|
# rbs_inline: enabled
|
2
2
|
|
3
3
|
module Wardite
|
4
|
+
module ValueHelper
|
5
|
+
# @rbs value: Integer
|
6
|
+
# @rbs return: I32
|
7
|
+
def I32(value)
|
8
|
+
if value < 0
|
9
|
+
$stderr.puts "debug: negative i32 value #{value} is passed, convert to unsigned"
|
10
|
+
value = as_u32(value)
|
11
|
+
end
|
12
|
+
I32.new.tap{|i| i.value = value & I32::I32_MAX }
|
13
|
+
end
|
14
|
+
|
15
|
+
# @rbs value: Integer
|
16
|
+
# @rbs return: I64
|
17
|
+
def I64(value)
|
18
|
+
if value < 0
|
19
|
+
$stderr.puts "debug: negative i64 value #{value} is passed, convert to unsigned"
|
20
|
+
value = as_u64(value)
|
21
|
+
end
|
22
|
+
I64.new.tap{|i| i.value = value & I64::I64_MAX }
|
23
|
+
end
|
24
|
+
|
25
|
+
# @rbs value: Float
|
26
|
+
# @rbs return: F32
|
27
|
+
def F32(value)
|
28
|
+
F32.new.tap{|i| i.value = value }
|
29
|
+
end
|
30
|
+
|
31
|
+
# @rbs value: Float
|
32
|
+
# @rbs return: F64
|
33
|
+
def F64(value)
|
34
|
+
F64.new.tap{|i| i.value = value }
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
# @rbs value: Integer
|
39
|
+
# @rbs return: Integer
|
40
|
+
def as_u32(value)
|
41
|
+
((-value) ^ I32::I32_MAX) + 1
|
42
|
+
end
|
43
|
+
|
44
|
+
# @rbs value: Integer
|
45
|
+
# @rbs return: Integer
|
46
|
+
def as_u64(value)
|
47
|
+
((-value) ^ I64::I64_MAX) + 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
extend ValueHelper
|
52
|
+
|
4
53
|
class I32
|
54
|
+
include ValueHelper
|
55
|
+
|
56
|
+
I32_MAX = (1<<32) - 1
|
57
|
+
# value should be stored as unsigned Integer, even in I32/I64
|
58
|
+
# when we want to access signed value, it'd be done via #value_s
|
5
59
|
attr_accessor :value #: Integer
|
6
60
|
|
61
|
+
# @rbs str: String
|
62
|
+
# @rbs size: Integer|nil
|
63
|
+
# @rbs signed: bool
|
64
|
+
# @rbs return: I32
|
65
|
+
def self.from_bytes(str, size: nil, signed: false)
|
66
|
+
v = case size
|
67
|
+
when nil
|
68
|
+
str.unpack("I!")[0]
|
69
|
+
when 8
|
70
|
+
signed ? str.unpack("c")[0] : str.unpack("C")[0]
|
71
|
+
when 16
|
72
|
+
signed ? str.unpack("s!")[0] : str.unpack("S!")[0]
|
73
|
+
end
|
74
|
+
if !v.is_a?(Integer)
|
75
|
+
raise "broken string or unsupported size: #{str.inspect} -> #{size}"
|
76
|
+
end
|
77
|
+
Wardite::I32(v)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @rbs return: Integer
|
81
|
+
def memsize
|
82
|
+
32
|
83
|
+
end
|
84
|
+
|
85
|
+
# returns a value interpreted as signed integer
|
86
|
+
# @rbs return: Integer
|
87
|
+
def value_s
|
88
|
+
(@value >> 31).zero? ?
|
89
|
+
@value :
|
90
|
+
((-@value) ^ I32_MAX) + 1
|
91
|
+
end
|
92
|
+
|
7
93
|
# TODO: eliminate use of pack, to support mruby - in this file!
|
94
|
+
# @rbs size: Integer|nil
|
8
95
|
# @rbs return: String
|
9
|
-
def packed
|
10
|
-
|
96
|
+
def packed(size: nil)
|
97
|
+
case size
|
98
|
+
when nil
|
99
|
+
[self.value].pack("I!")
|
100
|
+
when 8
|
101
|
+
[self.value & 0xff].pack("C")
|
102
|
+
when 16
|
103
|
+
[self.value & 0xffff].pack("S!")
|
104
|
+
else
|
105
|
+
raise EvalError, "unsupported size #{size}"
|
106
|
+
end
|
11
107
|
end
|
12
108
|
|
109
|
+
# @rbs to: Symbol
|
110
|
+
# @rbs return: I32|I64|F32|F64
|
111
|
+
def wrap(to:)
|
112
|
+
raise EvalError, "unsupported operation"
|
113
|
+
end
|
114
|
+
|
115
|
+
# @rbs to: Symbol
|
116
|
+
# @rbs return: I32|I64|F32|F64
|
117
|
+
def extend_s(to:)
|
118
|
+
raise EvalError, "unsupported operation" if to != :i64
|
119
|
+
I64(value_s)
|
120
|
+
end
|
121
|
+
|
122
|
+
# @rbs to: Symbol
|
123
|
+
# @rbs return: I32|I64|F32|F64
|
124
|
+
def extend_u(to:)
|
125
|
+
raise EvalError, "unsupported operation" if to != :i64
|
126
|
+
I64(value)
|
127
|
+
end
|
128
|
+
|
129
|
+
# @rbs to: Symbol
|
130
|
+
# @rbs return: I32|I64|F32|F64
|
131
|
+
def trunc_s(to:)
|
132
|
+
raise EvalError, "unsupported operation"
|
133
|
+
end
|
134
|
+
|
135
|
+
# @rbs to: Symbol
|
136
|
+
# @rbs return: I32|I64|F32|F64
|
137
|
+
def trunc_u(to:)
|
138
|
+
raise EvalError, "unsupported operation"
|
139
|
+
end
|
140
|
+
|
141
|
+
# @rbs to: Symbol
|
142
|
+
# @rbs return: I32|I64|F32|F64
|
143
|
+
def convert_s(to:)
|
144
|
+
case to
|
145
|
+
when :f32
|
146
|
+
F32(value_s.to_f)
|
147
|
+
when :f64
|
148
|
+
F64(value_s.to_f)
|
149
|
+
else
|
150
|
+
raise EvalError, "unsupported operation"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# @rbs to: Symbol
|
155
|
+
# @rbs return: I32|I64|F32|F64
|
156
|
+
def convert_u(to:)
|
157
|
+
case to
|
158
|
+
when :f32
|
159
|
+
F32(value.to_f)
|
160
|
+
when :f64
|
161
|
+
F64(value.to_f)
|
162
|
+
else
|
163
|
+
raise EvalError, "unsupported operation"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# @rbs to: Symbol
|
168
|
+
# @rbs return: I32|I64|F32|F64
|
169
|
+
def demote(to:)
|
170
|
+
raise EvalError, "unsupported operation"
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
# @rbs to: Symbol
|
175
|
+
# @rbs return: I32|I64|F32|F64
|
176
|
+
def promote(to:)
|
177
|
+
raise EvalError, "unsupported operation"
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
# @rbs to: Symbol
|
182
|
+
# @rbs return: I32|I64|F32|F64
|
183
|
+
def reinterpret(to:)
|
184
|
+
raise EvalError, "unsupported operation" if to != :f32
|
185
|
+
v = [value].pack("I!").unpack("f")[0]
|
186
|
+
raise EvalError, "[BUG] String#unpack is broke, really?" if !v.is_a?(Float)
|
187
|
+
F32(v)
|
188
|
+
end
|
189
|
+
|
190
|
+
# I32#inspect shows signed value for convinience
|
13
191
|
def inspect
|
14
|
-
"I32(#{
|
192
|
+
"I32(#{value_s})"
|
15
193
|
end
|
16
194
|
end
|
17
195
|
|
18
196
|
class I64
|
197
|
+
include ValueHelper
|
198
|
+
|
199
|
+
I64_MAX = (1<<64) - 1
|
200
|
+
|
19
201
|
attr_accessor :value #: Integer
|
20
202
|
|
203
|
+
# @rbs str: String
|
204
|
+
# @rbs size: Integer|nil
|
205
|
+
# @rbs signed: bool
|
206
|
+
# @rbs return: I64
|
207
|
+
def self.from_bytes(str, size: nil, signed: false)
|
208
|
+
v = case size
|
209
|
+
when nil
|
210
|
+
str.unpack("L!")[0]
|
211
|
+
when 8
|
212
|
+
signed ? str.unpack("c")[0] : str.unpack("C")[0]
|
213
|
+
when 16
|
214
|
+
signed ? str.unpack("s!")[0] : str.unpack("S!")[0]
|
215
|
+
when 32
|
216
|
+
signed ? str.unpack("i!")[0] : str.unpack("I!")[0]
|
217
|
+
end
|
218
|
+
if !v.is_a?(Integer)
|
219
|
+
raise "broken string or unsupported size: #{str.inspect} -> #{size}"
|
220
|
+
end
|
221
|
+
Wardite::I64(v)
|
222
|
+
end
|
223
|
+
|
224
|
+
# @rbs return: Integer
|
225
|
+
def memsize
|
226
|
+
64
|
227
|
+
end
|
228
|
+
|
229
|
+
# returns a value interpreted as signed integer
|
230
|
+
# @rbs return: Integer
|
231
|
+
def value_s
|
232
|
+
(@value >> 63).zero? ?
|
233
|
+
@value :
|
234
|
+
((-@value) ^ I64_MAX) + 1
|
235
|
+
end
|
236
|
+
|
237
|
+
# @rbs size: Integer|nil
|
21
238
|
# @rbs return: String
|
22
|
-
def packed
|
23
|
-
|
239
|
+
def packed(size: nil)
|
240
|
+
case size
|
241
|
+
when nil
|
242
|
+
[self.value].pack("L!")
|
243
|
+
when 8
|
244
|
+
[self.value & 0xff].pack("C")
|
245
|
+
when 16
|
246
|
+
[self.value & 0xffff].pack("S!")
|
247
|
+
when 32
|
248
|
+
[self.value & 0xffffffff].pack("I!")
|
249
|
+
else
|
250
|
+
raise EvalError, "unsupported size #{size}"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# @rbs to: Symbol
|
255
|
+
# @rbs return: I32|I64|F32|F64
|
256
|
+
def wrap(to:)
|
257
|
+
if to != :i32
|
258
|
+
raise EvalError, "unsupported operation #{to}"
|
259
|
+
end
|
260
|
+
I32(value % (1 << 32))
|
261
|
+
end
|
262
|
+
|
263
|
+
# @rbs to: Symbol
|
264
|
+
# @rbs return: I32|I64|F32|F64
|
265
|
+
def extend_s(to:)
|
266
|
+
raise EvalError, "unsupported operation"
|
267
|
+
end
|
268
|
+
|
269
|
+
# @rbs to: Symbol
|
270
|
+
# @rbs return: I32|I64|F32|F64
|
271
|
+
def extend_u(to:)
|
272
|
+
raise EvalError, "unsupported operation"
|
273
|
+
end
|
274
|
+
|
275
|
+
# @rbs to: Symbol
|
276
|
+
# @rbs return: I32|I64|F32|F64
|
277
|
+
def trunc_s(to:)
|
278
|
+
raise EvalError, "unsupported operation"
|
279
|
+
end
|
280
|
+
|
281
|
+
# @rbs to: Symbol
|
282
|
+
# @rbs return: I32|I64|F32|F64
|
283
|
+
def trunc_u(to:)
|
284
|
+
raise EvalError, "unsupported operation"
|
285
|
+
end
|
286
|
+
|
287
|
+
# @rbs to: Symbol
|
288
|
+
# @rbs return: I32|I64|F32|F64
|
289
|
+
def convert_s(to:)
|
290
|
+
case to
|
291
|
+
when :f32
|
292
|
+
F32(value_s.to_f)
|
293
|
+
when :f64
|
294
|
+
F64(value_s.to_f)
|
295
|
+
else
|
296
|
+
raise EvalError, "unsupported operation"
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
# @rbs to: Symbol
|
301
|
+
# @rbs return: I32|I64|F32|F64
|
302
|
+
def convert_u(to:)
|
303
|
+
case to
|
304
|
+
when :f32
|
305
|
+
F32(value.to_f)
|
306
|
+
when :f64
|
307
|
+
F64(value.to_f)
|
308
|
+
else
|
309
|
+
raise EvalError, "unsupported operation"
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# @rbs to: Symbol
|
314
|
+
# @rbs return: I32|I64|F32|F64
|
315
|
+
def demote(to:)
|
316
|
+
raise EvalError, "unsupported operation"
|
317
|
+
end
|
318
|
+
|
319
|
+
# @rbs to: Symbol
|
320
|
+
# @rbs return: I32|I64|F32|F64
|
321
|
+
def promote(to:)
|
322
|
+
raise EvalError, "unsupported operation"
|
323
|
+
end
|
324
|
+
|
325
|
+
# @rbs to: Symbol
|
326
|
+
# @rbs return: I32|I64|F32|F64
|
327
|
+
def reinterpret(to:)
|
328
|
+
raise EvalError, "unsupported operation" if to != :f64
|
329
|
+
v = [value].pack("L!").unpack("d")[0]
|
330
|
+
raise EvalError, "[BUG] String#unpack is broke, really?" if !v.is_a?(Float)
|
331
|
+
F32(v)
|
24
332
|
end
|
25
333
|
|
334
|
+
# I64#inspect shows signed value
|
26
335
|
def inspect
|
27
336
|
"I64(#{@value})"
|
28
337
|
end
|
29
338
|
end
|
30
339
|
|
31
340
|
class F32
|
32
|
-
|
341
|
+
include ValueHelper
|
342
|
+
|
343
|
+
attr_accessor :value #: Float
|
344
|
+
|
345
|
+
# @rbs str: String
|
346
|
+
# @rbs return: F32
|
347
|
+
def self.from_bytes(str)
|
348
|
+
v = str.unpack("e")[0]
|
349
|
+
if !v.is_a?(Float)
|
350
|
+
raise "broken string or unsupported size: #{str.inspect} -> 4"
|
351
|
+
end
|
352
|
+
Wardite::F32(v)
|
353
|
+
end
|
33
354
|
|
355
|
+
# @rbs return: Integer
|
356
|
+
def memsize
|
357
|
+
32
|
358
|
+
end
|
359
|
+
|
360
|
+
# @rbs return: :positive|:negative
|
361
|
+
def sign
|
362
|
+
upper = [0.0].pack("G")[0]&.ord&.<<(7)
|
363
|
+
if !upper
|
364
|
+
raise "[BUG] Array#pack looks broken?"
|
365
|
+
end
|
366
|
+
upper.zero? ? :positive : :negative
|
367
|
+
end
|
368
|
+
|
369
|
+
# @rbs size: Integer|nil
|
34
370
|
# @rbs return: String
|
35
|
-
def packed
|
36
|
-
[self.value].pack("
|
371
|
+
def packed(size: nil)
|
372
|
+
[self.value].pack("e")
|
373
|
+
end
|
374
|
+
|
375
|
+
# @rbs to: Symbol
|
376
|
+
# @rbs return: I32|I64|F32|F64
|
377
|
+
def wrap(to:)
|
378
|
+
raise EvalError, "unsupported operation"
|
379
|
+
end
|
380
|
+
|
381
|
+
# @rbs to: Symbol
|
382
|
+
# @rbs return: I32|I64|F32|F64
|
383
|
+
def extend_s(to:)
|
384
|
+
raise EvalError, "unsupported operation"
|
385
|
+
end
|
386
|
+
|
387
|
+
# @rbs to: Symbol
|
388
|
+
# @rbs return: I32|I64|F32|F64
|
389
|
+
def extend_u(to:)
|
390
|
+
raise EvalError, "unsupported operation"
|
391
|
+
end
|
392
|
+
|
393
|
+
# @todo need more testcase...
|
394
|
+
# @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-s-mathrm-trunc-mathsf-s-m-n-z
|
395
|
+
# @rbs to: Symbol
|
396
|
+
# @rbs return: I32|I64|F32|F64
|
397
|
+
def trunc_s(to:)
|
398
|
+
v = value.to_i
|
399
|
+
case to
|
400
|
+
when :i32
|
401
|
+
if v >= 0
|
402
|
+
I32(v & (I32::I32_MAX >> 1))
|
403
|
+
else
|
404
|
+
v = v & I32::I32_MAX
|
405
|
+
if (v >> 31).zero?
|
406
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
407
|
+
end
|
408
|
+
I32(v)
|
409
|
+
end
|
410
|
+
when :i64
|
411
|
+
if v >= 0
|
412
|
+
I64(v & (I64::I64_MAX >> 1))
|
413
|
+
else
|
414
|
+
v = v & I64::I64_MAX
|
415
|
+
if (v >> 31).zero?
|
416
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
417
|
+
end
|
418
|
+
I64(v)
|
419
|
+
end
|
420
|
+
else
|
421
|
+
raise EvalError, "unsupported operation to: #{to}"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
# @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-u-mathrm-trunc-mathsf-u-m-n-z
|
426
|
+
# @rbs to: Symbol
|
427
|
+
# @rbs return: I32|I64|F32|F64
|
428
|
+
def trunc_u(to:)
|
429
|
+
v = value.to_i
|
430
|
+
if v < 0
|
431
|
+
raise EvalError, "[undefined behavior] unexpected negative value"
|
432
|
+
end
|
433
|
+
case to
|
434
|
+
when :i32
|
435
|
+
v = v & I32::I32_MAX
|
436
|
+
I32(v)
|
437
|
+
when :i64
|
438
|
+
v = v & I64::I64_MAX
|
439
|
+
I64(v)
|
440
|
+
else
|
441
|
+
raise EvalError, "unsupported operation to: #{to}"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
# @rbs to: Symbol
|
446
|
+
# @rbs return: I32|I64|F32|F64
|
447
|
+
def convert_s(to:)
|
448
|
+
raise EvalError, "unsupported operation"
|
449
|
+
end
|
450
|
+
|
451
|
+
# @rbs to: Symbol
|
452
|
+
# @rbs return: I32|I64|F32|F64
|
453
|
+
def convert_u(to:)
|
454
|
+
raise EvalError, "unsupported operation"
|
455
|
+
end
|
456
|
+
|
457
|
+
# @rbs to: Symbol
|
458
|
+
# @rbs return: I32|I64|F32|F64
|
459
|
+
def demote(to:)
|
460
|
+
raise EvalError, "unsupported operation"
|
461
|
+
end
|
462
|
+
|
463
|
+
# @rbs to: Symbol
|
464
|
+
# @rbs return: I32|I64|F32|F64
|
465
|
+
def promote(to:)
|
466
|
+
raise EvalError, "unsupported operation" if to != :f64
|
467
|
+
F64(value)
|
468
|
+
end
|
469
|
+
|
470
|
+
# @rbs to: Symbol
|
471
|
+
# @rbs return: I32|I64|F32|F64
|
472
|
+
def reinterpret(to:)
|
473
|
+
raise EvalError, "unsupported operation" if to != :i32
|
474
|
+
v = [value].pack("f").unpack("I!")[0]
|
475
|
+
raise EvalError, "[BUG] String#unpack is broke, really?" if !v.is_a?(Integer)
|
476
|
+
I32(v)
|
37
477
|
end
|
38
478
|
|
39
479
|
def inspect
|
@@ -42,41 +482,146 @@ module Wardite
|
|
42
482
|
end
|
43
483
|
|
44
484
|
class F64
|
45
|
-
|
485
|
+
include ValueHelper
|
486
|
+
|
487
|
+
attr_accessor :value #: Float
|
46
488
|
|
489
|
+
# @rbs str: String
|
490
|
+
# @rbs return: F64
|
491
|
+
def self.from_bytes(str)
|
492
|
+
v = str.unpack("E")[0]
|
493
|
+
if !v.is_a?(Float)
|
494
|
+
raise "broken string or unsupported size: #{str.inspect} -> 8"
|
495
|
+
end
|
496
|
+
Wardite::F64(v)
|
497
|
+
end
|
498
|
+
|
499
|
+
# @rbs return: Integer
|
500
|
+
def memsize
|
501
|
+
64
|
502
|
+
end
|
503
|
+
|
504
|
+
# @rbs return: :positive|:negative
|
505
|
+
def sign
|
506
|
+
upper = [0.0].pack("G")[0]&.ord&.<<(7)
|
507
|
+
if !upper
|
508
|
+
raise "[BUG] Array#pack looks broken?"
|
509
|
+
end
|
510
|
+
upper.zero? ? :positive : :negative
|
511
|
+
end
|
512
|
+
|
513
|
+
# @rbs size: Integer|nil
|
47
514
|
# @rbs return: String
|
48
|
-
def packed
|
49
|
-
[self.value].pack("
|
515
|
+
def packed(size: nil)
|
516
|
+
[self.value].pack("E")
|
50
517
|
end
|
51
518
|
|
52
|
-
|
53
|
-
|
519
|
+
# @rbs to: Symbol
|
520
|
+
# @rbs return: I32|I64|F32|F64
|
521
|
+
def wrap(to:)
|
522
|
+
raise EvalError, "unsupported operation"
|
54
523
|
end
|
55
|
-
end
|
56
524
|
|
57
|
-
|
58
|
-
# @rbs
|
59
|
-
|
60
|
-
|
61
|
-
I32.new.tap{|i| i.value = value }
|
525
|
+
# @rbs to: Symbol
|
526
|
+
# @rbs return: I32|I64|F32|F64
|
527
|
+
def extend_s(to:)
|
528
|
+
raise EvalError, "unsupported operation"
|
62
529
|
end
|
63
530
|
|
64
|
-
# @rbs
|
65
|
-
# @rbs return: I64
|
66
|
-
def
|
67
|
-
|
531
|
+
# @rbs to: Symbol
|
532
|
+
# @rbs return: I32|I64|F32|F64
|
533
|
+
def extend_u(to:)
|
534
|
+
raise EvalError, "unsupported operation"
|
68
535
|
end
|
69
536
|
|
70
|
-
# @
|
71
|
-
# @rbs
|
72
|
-
|
73
|
-
|
537
|
+
# @see the same as F32
|
538
|
+
# @rbs to: Symbol
|
539
|
+
# @rbs return: I32|I64|F32|F64
|
540
|
+
def trunc_s(to:)
|
541
|
+
v = value.to_i
|
542
|
+
case to
|
543
|
+
when :i32
|
544
|
+
if v >= 0
|
545
|
+
I32(v & (I32::I32_MAX >> 1))
|
546
|
+
else
|
547
|
+
v = v & I32::I32_MAX
|
548
|
+
if (v >> 31).zero?
|
549
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
550
|
+
end
|
551
|
+
I32(v)
|
552
|
+
end
|
553
|
+
when :i64
|
554
|
+
if v >= 0
|
555
|
+
I64(v & (I64::I64_MAX >> 1))
|
556
|
+
else
|
557
|
+
v = v & I64::I64_MAX
|
558
|
+
if (v >> 31).zero?
|
559
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
560
|
+
end
|
561
|
+
I64(v)
|
562
|
+
end
|
563
|
+
else
|
564
|
+
raise EvalError, "unsupported operation to: #{to}"
|
565
|
+
end
|
74
566
|
end
|
75
567
|
|
76
|
-
# @
|
77
|
-
# @rbs
|
78
|
-
|
79
|
-
|
568
|
+
# @see the same as F32
|
569
|
+
# @rbs to: Symbol
|
570
|
+
# @rbs return: I32|I64|F32|F64
|
571
|
+
def trunc_u(to:)
|
572
|
+
v = value.to_i
|
573
|
+
if v < 0
|
574
|
+
raise EvalError, "[undefined behavior] unexpected negative value"
|
575
|
+
end
|
576
|
+
case to
|
577
|
+
when :i32
|
578
|
+
v = v & I32::I32_MAX
|
579
|
+
I32(v)
|
580
|
+
when :i64
|
581
|
+
v = v & I64::I64_MAX
|
582
|
+
I64(v)
|
583
|
+
else
|
584
|
+
raise EvalError, "unsupported operation to: #{to}"
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
# @rbs to: Symbol
|
589
|
+
# @rbs return: I32|I64|F32|F64
|
590
|
+
def convert_s(to:)
|
591
|
+
raise EvalError, "unsupported operation"
|
592
|
+
end
|
593
|
+
|
594
|
+
# @rbs to: Symbol
|
595
|
+
# @rbs return: I32|I64|F32|F64
|
596
|
+
def convert_u(to:)
|
597
|
+
raise EvalError, "unsupported operation"
|
598
|
+
end
|
599
|
+
|
600
|
+
# @todo no loss of digits...
|
601
|
+
# @rbs to: Symbol
|
602
|
+
# @rbs return: I32|I64|F32|F64
|
603
|
+
def demote(to:)
|
604
|
+
raise EvalError, "unsupported operation" if to != :f32
|
605
|
+
F32(value)
|
606
|
+
end
|
607
|
+
|
608
|
+
# @rbs to: Symbol
|
609
|
+
# @rbs return: I32|I64|F32|F64
|
610
|
+
def promote(to:)
|
611
|
+
raise EvalError, "unsupported operation"
|
612
|
+
end
|
613
|
+
|
614
|
+
# @rbs to: Symbol
|
615
|
+
# @rbs return: I32|I64|F32|F64
|
616
|
+
def reinterpret(to:)
|
617
|
+
raise EvalError, "unsupported operation" if to != :i64
|
618
|
+
v = [value].pack("d").unpack("L!")[0]
|
619
|
+
raise EvalError, "[BUG] String#unpack is broke, really?" if !v.is_a?(Integer)
|
620
|
+
I64(v)
|
621
|
+
end
|
622
|
+
|
623
|
+
def inspect
|
624
|
+
"F64(#{@value})"
|
80
625
|
end
|
81
626
|
end
|
82
627
|
end
|
data/lib/wardite/version.rb
CHANGED