wardite 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/wardite/value.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  # rbs_inline: enabled
2
2
 
3
3
  module Wardite
4
+ # @rbs!
5
+ # type wasmValue = I32 | I64 | F32 | F64
6
+
4
7
  module ValueHelper
5
8
  # @rbs value: Integer
6
9
  # @rbs return: I32
7
10
  def I32(value)
8
11
  if value < 0
9
- $stderr.puts "debug: negative i32 value #{value} is passed, convert to unsigned"
12
+ # $stderr.puts "trace: negative i32 value #{value} is passed, convert to unsigned"
10
13
  value = as_u32(value)
11
14
  end
12
15
  I32.new.tap{|i| i.value = value & I32::I32_MAX }
@@ -16,7 +19,7 @@ module Wardite
16
19
  # @rbs return: I64
17
20
  def I64(value)
18
21
  if value < 0
19
- $stderr.puts "debug: negative i64 value #{value} is passed, convert to unsigned"
22
+ # $stderr.puts "trace: negative i64 value #{value} is passed, convert to unsigned"
20
23
  value = as_u64(value)
21
24
  end
22
25
  I64.new.tap{|i| i.value = value & I64::I64_MAX }
@@ -53,7 +56,7 @@ module Wardite
53
56
  class I32
54
57
  include ValueHelper
55
58
 
56
- I32_MAX = (1<<32) - 1
59
+ I32_MAX = (1<<32) - 1 #: Integer
57
60
  # value should be stored as unsigned Integer, even in I32/I64
58
61
  # when we want to access signed value, it'd be done via #value_s
59
62
  attr_accessor :value #: Integer
@@ -107,39 +110,39 @@ module Wardite
107
110
  end
108
111
 
109
112
  # @rbs to: Symbol
110
- # @rbs return: I32|I64|F32|F64
113
+ # @rbs return: wasmValue
111
114
  def wrap(to:)
112
115
  raise EvalError, "unsupported operation"
113
116
  end
114
117
 
115
118
  # @rbs to: Symbol
116
- # @rbs return: I32|I64|F32|F64
119
+ # @rbs return: wasmValue
117
120
  def extend_s(to:)
118
121
  raise EvalError, "unsupported operation" if to != :i64
119
122
  I64(value_s)
120
123
  end
121
124
 
122
125
  # @rbs to: Symbol
123
- # @rbs return: I32|I64|F32|F64
126
+ # @rbs return: wasmValue
124
127
  def extend_u(to:)
125
128
  raise EvalError, "unsupported operation" if to != :i64
126
129
  I64(value)
127
130
  end
128
131
 
129
132
  # @rbs to: Symbol
130
- # @rbs return: I32|I64|F32|F64
133
+ # @rbs return: wasmValue
131
134
  def trunc_s(to:)
132
135
  raise EvalError, "unsupported operation"
133
136
  end
134
137
 
135
138
  # @rbs to: Symbol
136
- # @rbs return: I32|I64|F32|F64
139
+ # @rbs return: wasmValue
137
140
  def trunc_u(to:)
138
141
  raise EvalError, "unsupported operation"
139
142
  end
140
143
 
141
144
  # @rbs to: Symbol
142
- # @rbs return: I32|I64|F32|F64
145
+ # @rbs return: wasmValue
143
146
  def convert_s(to:)
144
147
  case to
145
148
  when :f32
@@ -152,7 +155,7 @@ module Wardite
152
155
  end
153
156
 
154
157
  # @rbs to: Symbol
155
- # @rbs return: I32|I64|F32|F64
158
+ # @rbs return: wasmValue
156
159
  def convert_u(to:)
157
160
  case to
158
161
  when :f32
@@ -165,21 +168,21 @@ module Wardite
165
168
  end
166
169
 
167
170
  # @rbs to: Symbol
168
- # @rbs return: I32|I64|F32|F64
171
+ # @rbs return: wasmValue
169
172
  def demote(to:)
170
173
  raise EvalError, "unsupported operation"
171
174
 
172
175
  end
173
176
 
174
177
  # @rbs to: Symbol
175
- # @rbs return: I32|I64|F32|F64
178
+ # @rbs return: wasmValue
176
179
  def promote(to:)
177
180
  raise EvalError, "unsupported operation"
178
181
 
179
182
  end
180
183
 
181
184
  # @rbs to: Symbol
182
- # @rbs return: I32|I64|F32|F64
185
+ # @rbs return: wasmValue
183
186
  def reinterpret(to:)
184
187
  raise EvalError, "unsupported operation" if to != :f32
185
188
  v = [value].pack("I!").unpack("f")[0]
@@ -187,6 +190,49 @@ module Wardite
187
190
  F32(v)
188
191
  end
189
192
 
193
+ # @rbs from: Symbol
194
+ # @rbs to: Symbol
195
+ # @rbs return: wasmValue
196
+ def extendN_s(from:, to:)
197
+ src_value = case from
198
+ when :i8
199
+ base = value & 0xff
200
+ (base >> 8).zero? ?
201
+ base :
202
+ ((-base) ^ 0xff) + 1
203
+ when :i16
204
+ base = value & 0xffff
205
+ (base >> 15).zero? ?
206
+ base :
207
+ ((-base) ^ 0xffff) + 1
208
+ when :i32
209
+ value_s
210
+ else
211
+ raise EvalError, "unsupported value size"
212
+ end
213
+
214
+ case to
215
+ when :i32
216
+ I32(src_value)
217
+ when :i64
218
+ I64(src_value)
219
+ else
220
+ raise EvalError, "unsupported value size"
221
+ end
222
+ end
223
+
224
+ # @rbs to: Symbol
225
+ # @rbs return: wasmValue
226
+ def trunc_sat_u(to:)
227
+ raise EvalError, "unsupported operation"
228
+ end
229
+
230
+ # @rbs to: Symbol
231
+ # @rbs return: wasmValue
232
+ def trunc_sat_s(to:)
233
+ raise EvalError, "unsupported operation"
234
+ end
235
+
190
236
  # I32#inspect shows signed value for convinience
191
237
  def inspect
192
238
  "I32(#{value_s})"
@@ -196,7 +242,7 @@ module Wardite
196
242
  class I64
197
243
  include ValueHelper
198
244
 
199
- I64_MAX = (1<<64) - 1
245
+ I64_MAX = (1<<64) - 1 #: Integer
200
246
 
201
247
  attr_accessor :value #: Integer
202
248
 
@@ -252,7 +298,7 @@ module Wardite
252
298
  end
253
299
 
254
300
  # @rbs to: Symbol
255
- # @rbs return: I32|I64|F32|F64
301
+ # @rbs return: wasmValue
256
302
  def wrap(to:)
257
303
  if to != :i32
258
304
  raise EvalError, "unsupported operation #{to}"
@@ -261,31 +307,31 @@ module Wardite
261
307
  end
262
308
 
263
309
  # @rbs to: Symbol
264
- # @rbs return: I32|I64|F32|F64
310
+ # @rbs return: wasmValue
265
311
  def extend_s(to:)
266
312
  raise EvalError, "unsupported operation"
267
313
  end
268
314
 
269
315
  # @rbs to: Symbol
270
- # @rbs return: I32|I64|F32|F64
316
+ # @rbs return: wasmValue
271
317
  def extend_u(to:)
272
318
  raise EvalError, "unsupported operation"
273
319
  end
274
320
 
275
321
  # @rbs to: Symbol
276
- # @rbs return: I32|I64|F32|F64
322
+ # @rbs return: wasmValue
277
323
  def trunc_s(to:)
278
324
  raise EvalError, "unsupported operation"
279
325
  end
280
326
 
281
327
  # @rbs to: Symbol
282
- # @rbs return: I32|I64|F32|F64
328
+ # @rbs return: wasmValue
283
329
  def trunc_u(to:)
284
330
  raise EvalError, "unsupported operation"
285
331
  end
286
332
 
287
333
  # @rbs to: Symbol
288
- # @rbs return: I32|I64|F32|F64
334
+ # @rbs return: wasmValue
289
335
  def convert_s(to:)
290
336
  case to
291
337
  when :f32
@@ -298,7 +344,7 @@ module Wardite
298
344
  end
299
345
 
300
346
  # @rbs to: Symbol
301
- # @rbs return: I32|I64|F32|F64
347
+ # @rbs return: wasmValue
302
348
  def convert_u(to:)
303
349
  case to
304
350
  when :f32
@@ -311,19 +357,19 @@ module Wardite
311
357
  end
312
358
 
313
359
  # @rbs to: Symbol
314
- # @rbs return: I32|I64|F32|F64
360
+ # @rbs return: wasmValue
315
361
  def demote(to:)
316
362
  raise EvalError, "unsupported operation"
317
363
  end
318
364
 
319
365
  # @rbs to: Symbol
320
- # @rbs return: I32|I64|F32|F64
366
+ # @rbs return: wasmValue
321
367
  def promote(to:)
322
368
  raise EvalError, "unsupported operation"
323
369
  end
324
370
 
325
371
  # @rbs to: Symbol
326
- # @rbs return: I32|I64|F32|F64
372
+ # @rbs return: wasmValue
327
373
  def reinterpret(to:)
328
374
  raise EvalError, "unsupported operation" if to != :f64
329
375
  v = [value].pack("L!").unpack("d")[0]
@@ -331,6 +377,25 @@ module Wardite
331
377
  F32(v)
332
378
  end
333
379
 
380
+ # @rbs from: Symbol
381
+ # @rbs to: Symbol
382
+ # @rbs return: wasmValue
383
+ def extendN_s(from:, to:)
384
+ raise EvalError, "unsupported operation"
385
+ end
386
+
387
+ # @rbs to: Symbol
388
+ # @rbs return: wasmValue
389
+ def trunc_sat_u(to:)
390
+ raise EvalError, "unsupported operation"
391
+ end
392
+
393
+ # @rbs to: Symbol
394
+ # @rbs return: wasmValue
395
+ def trunc_sat_s(to:)
396
+ raise EvalError, "unsupported operation"
397
+ end
398
+
334
399
  # I64#inspect shows signed value
335
400
  def inspect
336
401
  "I64(#{@value})"
@@ -373,47 +438,71 @@ module Wardite
373
438
  end
374
439
 
375
440
  # @rbs to: Symbol
376
- # @rbs return: I32|I64|F32|F64
441
+ # @rbs return: wasmValue
377
442
  def wrap(to:)
378
443
  raise EvalError, "unsupported operation"
379
444
  end
380
445
 
381
446
  # @rbs to: Symbol
382
- # @rbs return: I32|I64|F32|F64
447
+ # @rbs return: wasmValue
383
448
  def extend_s(to:)
384
449
  raise EvalError, "unsupported operation"
385
450
  end
386
451
 
387
452
  # @rbs to: Symbol
388
- # @rbs return: I32|I64|F32|F64
453
+ # @rbs return: wasmValue
389
454
  def extend_u(to:)
390
455
  raise EvalError, "unsupported operation"
391
456
  end
392
457
 
393
458
  # @todo need more testcase...
394
459
  # @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-s-mathrm-trunc-mathsf-s-m-n-z
460
+ # @see copy this impl to F64 when changed
395
461
  # @rbs to: Symbol
396
- # @rbs return: I32|I64|F32|F64
397
- def trunc_s(to:)
462
+ # @rbs saturating: bool
463
+ # @rbs return: wasmValue
464
+ def trunc_s(to:, saturating: false)
398
465
  v = value.to_i
399
466
  case to
400
467
  when :i32
401
468
  if v >= 0
402
- I32(v & (I32::I32_MAX >> 1))
469
+ i32_signed_max = I32::I32_MAX >> 1
470
+ if saturating
471
+ v = i32_signed_max if v > i32_signed_max
472
+ else
473
+ v = v & i32_signed_max
474
+ end
475
+ I32(v & i32_signed_max)
403
476
  else
404
- v = v & I32::I32_MAX
405
- if (v >> 31).zero?
406
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
477
+ i32_signed_min = -(I32::I32_MAX >> 1) - 1
478
+ if saturating
479
+ v = i32_signed_min if v < i32_signed_min
480
+ else
481
+ v = v & I32::I32_MAX
482
+ if (v >> 31).zero?
483
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
484
+ end
407
485
  end
408
486
  I32(v)
409
487
  end
410
488
  when :i64
411
489
  if v >= 0
412
- I64(v & (I64::I64_MAX >> 1))
490
+ i64_signed_max = I64::I64_MAX >> 1
491
+ if saturating
492
+ v = i64_signed_max if v > i64_signed_max
493
+ else
494
+ v = v & i64_signed_max
495
+ end
496
+ I64(v & i64_signed_max)
413
497
  else
414
- v = v & I64::I64_MAX
415
- if (v >> 31).zero?
416
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
498
+ i64_signed_min = -(I64::I64_MAX >> 1) - 1
499
+ if saturating
500
+ v = i64_signed_min if v < i64_signed_min
501
+ else
502
+ v = v & I64::I64_MAX
503
+ if (v >> 63).zero?
504
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
505
+ end
417
506
  end
418
507
  I64(v)
419
508
  end
@@ -423,19 +512,33 @@ module Wardite
423
512
  end
424
513
 
425
514
  # @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-u-mathrm-trunc-mathsf-u-m-n-z
515
+ # @see copy this impl to F64 when changed
426
516
  # @rbs to: Symbol
427
- # @rbs return: I32|I64|F32|F64
428
- def trunc_u(to:)
517
+ # @rbs sturating: bool
518
+ # @rbs return: wasmValue
519
+ def trunc_u(to:, saturating: false)
429
520
  v = value.to_i
430
521
  if v < 0
431
- raise EvalError, "[undefined behavior] unexpected negative value"
522
+ if saturating
523
+ v = 0
524
+ else
525
+ raise EvalError, "[undefined behavior] unexpected negative value"
526
+ end
432
527
  end
433
528
  case to
434
529
  when :i32
435
- v = v & I32::I32_MAX
530
+ if saturating
531
+ v = I32::I32_MAX if v > I32::I32_MAX
532
+ else
533
+ v = v & I32::I32_MAX
534
+ end
436
535
  I32(v)
437
536
  when :i64
438
- v = v & I64::I64_MAX
537
+ if saturating
538
+ v = I64::I64_MAX if v > I64::I64_MAX
539
+ else
540
+ v = v & I64::I64_MAX
541
+ end
439
542
  I64(v)
440
543
  else
441
544
  raise EvalError, "unsupported operation to: #{to}"
@@ -443,32 +546,32 @@ module Wardite
443
546
  end
444
547
 
445
548
  # @rbs to: Symbol
446
- # @rbs return: I32|I64|F32|F64
549
+ # @rbs return: wasmValue
447
550
  def convert_s(to:)
448
551
  raise EvalError, "unsupported operation"
449
552
  end
450
553
 
451
554
  # @rbs to: Symbol
452
- # @rbs return: I32|I64|F32|F64
555
+ # @rbs return: wasmValue
453
556
  def convert_u(to:)
454
557
  raise EvalError, "unsupported operation"
455
558
  end
456
559
 
457
560
  # @rbs to: Symbol
458
- # @rbs return: I32|I64|F32|F64
561
+ # @rbs return: wasmValue
459
562
  def demote(to:)
460
563
  raise EvalError, "unsupported operation"
461
564
  end
462
565
 
463
566
  # @rbs to: Symbol
464
- # @rbs return: I32|I64|F32|F64
567
+ # @rbs return: wasmValue
465
568
  def promote(to:)
466
569
  raise EvalError, "unsupported operation" if to != :f64
467
570
  F64(value)
468
571
  end
469
572
 
470
573
  # @rbs to: Symbol
471
- # @rbs return: I32|I64|F32|F64
574
+ # @rbs return: wasmValue
472
575
  def reinterpret(to:)
473
576
  raise EvalError, "unsupported operation" if to != :i32
474
577
  v = [value].pack("f").unpack("I!")[0]
@@ -476,6 +579,25 @@ module Wardite
476
579
  I32(v)
477
580
  end
478
581
 
582
+ # @rbs from: Symbol
583
+ # @rbs to: Symbol
584
+ # @rbs return: wasmValue
585
+ def extendN_s(from:, to:)
586
+ raise EvalError, "unsupported operation"
587
+ end
588
+
589
+ # @rbs to: Symbol
590
+ # @rbs return: wasmValue
591
+ def trunc_sat_u(to:)
592
+ trunc_u(to: to, saturating: true)
593
+ end
594
+
595
+ # @rbs to: Symbol
596
+ # @rbs return: wasmValue
597
+ def trunc_sat_s(to:)
598
+ trunc_s(to: to, saturating: true)
599
+ end
600
+
479
601
  def inspect
480
602
  "F32(#{@value})"
481
603
  end
@@ -517,46 +639,69 @@ module Wardite
517
639
  end
518
640
 
519
641
  # @rbs to: Symbol
520
- # @rbs return: I32|I64|F32|F64
642
+ # @rbs return: wasmValue
521
643
  def wrap(to:)
522
644
  raise EvalError, "unsupported operation"
523
645
  end
524
646
 
525
647
  # @rbs to: Symbol
526
- # @rbs return: I32|I64|F32|F64
648
+ # @rbs return: wasmValue
527
649
  def extend_s(to:)
528
650
  raise EvalError, "unsupported operation"
529
651
  end
530
652
 
531
653
  # @rbs to: Symbol
532
- # @rbs return: I32|I64|F32|F64
654
+ # @rbs return: wasmValue
533
655
  def extend_u(to:)
534
656
  raise EvalError, "unsupported operation"
535
657
  end
536
658
 
537
659
  # @see the same as F32
538
660
  # @rbs to: Symbol
539
- # @rbs return: I32|I64|F32|F64
540
- def trunc_s(to:)
661
+ # @rbs saturating: bool
662
+ # @rbs return: wasmValue
663
+ def trunc_s(to:, saturating: false)
541
664
  v = value.to_i
542
665
  case to
543
666
  when :i32
544
667
  if v >= 0
545
- I32(v & (I32::I32_MAX >> 1))
668
+ i32_signed_max = I32::I32_MAX >> 1
669
+ if saturating
670
+ v = i32_signed_max if v > i32_signed_max
671
+ else
672
+ v = v & i32_signed_max
673
+ end
674
+ I32(v & i32_signed_max)
546
675
  else
547
- v = v & I32::I32_MAX
548
- if (v >> 31).zero?
549
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
676
+ i32_signed_min = -(I32::I32_MAX >> 1) - 1
677
+ if saturating
678
+ v = i32_signed_min if v < i32_signed_min
679
+ else
680
+ v = v & I32::I32_MAX
681
+ if (v >> 31).zero?
682
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
683
+ end
550
684
  end
551
685
  I32(v)
552
686
  end
553
687
  when :i64
554
688
  if v >= 0
555
- I64(v & (I64::I64_MAX >> 1))
689
+ i64_signed_max = I64::I64_MAX >> 1
690
+ if saturating
691
+ v = i64_signed_max if v > i64_signed_max
692
+ else
693
+ v = v & i64_signed_max
694
+ end
695
+ I64(v & i64_signed_max)
556
696
  else
557
- v = v & I64::I64_MAX
558
- if (v >> 31).zero?
559
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
697
+ i64_signed_min = -(I64::I64_MAX >> 1) - 1
698
+ if saturating
699
+ v = i64_signed_min if v < i64_signed_min
700
+ else
701
+ v = v & I64::I64_MAX
702
+ if (v >> 63).zero?
703
+ raise EvalError, "[undefined behavior] detected overflow: #{value}"
704
+ end
560
705
  end
561
706
  I64(v)
562
707
  end
@@ -567,18 +712,31 @@ module Wardite
567
712
 
568
713
  # @see the same as F32
569
714
  # @rbs to: Symbol
570
- # @rbs return: I32|I64|F32|F64
571
- def trunc_u(to:)
715
+ # @rbs saturating: bool
716
+ # @rbs return: wasmValue
717
+ def trunc_u(to:, saturating: false)
572
718
  v = value.to_i
573
719
  if v < 0
574
- raise EvalError, "[undefined behavior] unexpected negative value"
720
+ if saturating
721
+ v = 0
722
+ else
723
+ raise EvalError, "[undefined behavior] unexpected negative value"
724
+ end
575
725
  end
576
726
  case to
577
727
  when :i32
578
- v = v & I32::I32_MAX
728
+ if saturating
729
+ v = I32::I32_MAX if v > I32::I32_MAX
730
+ else
731
+ v = v & I32::I32_MAX
732
+ end
579
733
  I32(v)
580
734
  when :i64
581
- v = v & I64::I64_MAX
735
+ if saturating
736
+ v = I64::I64_MAX if v > I64::I64_MAX
737
+ else
738
+ v = v & I64::I64_MAX
739
+ end
582
740
  I64(v)
583
741
  else
584
742
  raise EvalError, "unsupported operation to: #{to}"
@@ -586,33 +744,33 @@ module Wardite
586
744
  end
587
745
 
588
746
  # @rbs to: Symbol
589
- # @rbs return: I32|I64|F32|F64
747
+ # @rbs return: wasmValue
590
748
  def convert_s(to:)
591
749
  raise EvalError, "unsupported operation"
592
750
  end
593
751
 
594
752
  # @rbs to: Symbol
595
- # @rbs return: I32|I64|F32|F64
753
+ # @rbs return: wasmValue
596
754
  def convert_u(to:)
597
755
  raise EvalError, "unsupported operation"
598
756
  end
599
757
 
600
758
  # @todo no loss of digits...
601
759
  # @rbs to: Symbol
602
- # @rbs return: I32|I64|F32|F64
760
+ # @rbs return: wasmValue
603
761
  def demote(to:)
604
762
  raise EvalError, "unsupported operation" if to != :f32
605
763
  F32(value)
606
764
  end
607
765
 
608
766
  # @rbs to: Symbol
609
- # @rbs return: I32|I64|F32|F64
767
+ # @rbs return: wasmValue
610
768
  def promote(to:)
611
769
  raise EvalError, "unsupported operation"
612
770
  end
613
771
 
614
772
  # @rbs to: Symbol
615
- # @rbs return: I32|I64|F32|F64
773
+ # @rbs return: wasmValue
616
774
  def reinterpret(to:)
617
775
  raise EvalError, "unsupported operation" if to != :i64
618
776
  v = [value].pack("d").unpack("L!")[0]
@@ -620,6 +778,25 @@ module Wardite
620
778
  I64(v)
621
779
  end
622
780
 
781
+ # @rbs from: Symbol
782
+ # @rbs to: Symbol
783
+ # @rbs return: wasmValue
784
+ def extendN_s(from:, to:)
785
+ raise EvalError, "unsupported operation"
786
+ end
787
+
788
+ # @rbs to: Symbol
789
+ # @rbs return: wasmValue
790
+ def trunc_sat_u(to:)
791
+ trunc_u(to: to, saturating: true)
792
+ end
793
+
794
+ # @rbs to: Symbol
795
+ # @rbs return: wasmValue
796
+ def trunc_sat_s(to:)
797
+ trunc_s(to: to, saturating: true)
798
+ end
799
+
623
800
  def inspect
624
801
  "F64(#{@value})"
625
802
  end
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Wardite
5
- VERSION = "0.2.2" #: String
5
+ VERSION = "0.4.0" #: String
6
6
  end
data/lib/wardite/wasi.rb CHANGED
@@ -14,7 +14,7 @@ module Wardite
14
14
  end
15
15
 
16
16
  # @rbs store: Store
17
- # @rbs args: Array[I32|I64|F32|F64]
17
+ # @rbs args: Array[wasmValue]
18
18
  # @rbs return: Object
19
19
  def fd_write(store, args)
20
20
  iargs = args.map do |elm|
@@ -45,7 +45,7 @@ module Wardite
45
45
  0
46
46
  end
47
47
 
48
- # @rbs return: Hash[Symbol, Proc]
48
+ # @rbs return: Hash[Symbol, wasmCallable]
49
49
  def to_module
50
50
  {
51
51
  fd_write: lambda{|store, args| self.fd_write(store, args) },