wardite 0.4.3 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1960efc493205587db2fbb0e21504247d120831417b081dc169c0b7c10fccaf
4
- data.tar.gz: cbdbf5e122fe118ccee7a615b184be2032b6000a043b3642a9b5336f6b0fbe19
3
+ metadata.gz: 89b6c42e1a3f16c39c214eb127c5b87966c0d2933257a1da7fdc96236c6a0f9b
4
+ data.tar.gz: 321d62cdddc61c8a342b966b3e4d7b6c01ffbbcb5788a6787fd3490ba96b1430
5
5
  SHA512:
6
- metadata.gz: 207a1cd23ab5f25fdf9dd421ab42c70528be1987e57f41d656f47e205ee78ba321b9553364f988f6f039f87a77878e040075e690b00b97ace0bf91e35c07431f
7
- data.tar.gz: 944b8112be80c9c3b78dd7cdec01ac3c72f7e4e077196a315bfaa14ffeb4dfa6cdb868570ae0bc55fb4f07da858f968807fee8bb50d5846fa763dd7b82359f98
6
+ metadata.gz: 4b8b67989d47775828aca0908794f6b02abdea5ed653d794fa308d437f2d1735997a91dee341cdfa51aa5829aa097ca61dd262dba8479e805d1bbfd540f90ff5
7
+ data.tar.gz: 26face977ed4d76232bdee62f64208a22ec824314cb3d479979705fee327a1c9ce72ee960055a0c26db591f932c598b591651170fedf31b36533c52774f05fbe
@@ -0,0 +1,64 @@
1
+ #
2
+ # Usage:
3
+ # $ bundle exec ruby --yjit examples/grayscale.rb \
4
+ # --wasm-file path/to/grayscale.wasm \
5
+ # --source tmp/source.png \
6
+ # --dest tmp/result.png \
7
+ # --width 660 --height 495
8
+ #
9
+ require "wardite"
10
+ require "base64"
11
+ require "optparse"
12
+ require "ostruct"
13
+
14
+ $options = OpenStruct.new
15
+
16
+ opt = OptionParser.new
17
+ opt.on('--wasm-file [FILE]') {|v| $options.wasm_file = v }
18
+ opt.on('--source [IMAGE]') {|v| $options.source = v }
19
+ opt.on('--dest [IMAGE]') {|v| $options.dest = v }
20
+ opt.on('--width [W]') {|v| $options.width = v.to_i }
21
+ opt.on('--height [H]') {|v| $options.height = v.to_i }
22
+ opt.parse!
23
+
24
+ #require 'ruby-prof'
25
+ #profile = RubyProf::Profile.new
26
+
27
+ f = File.open($options.wasm_file)
28
+ data = IO.read($options.source)
29
+ orig = Base64.encode64(data).gsub(/(\r|\n)/, "")
30
+ data_url = "data:image/png;base64," + orig
31
+ instance = Wardite::BinaryLoader::load_from_buffer(f);
32
+ instance.store.memories[0].grow(data_url.size / (64*1024) + 1)
33
+
34
+ start = instance.exports.__heap_base.value.value
35
+ instance.store.memories[0].data[start...(start+data_url.size)] = data_url
36
+
37
+ offset = 0
38
+ result = nil
39
+ begin
40
+ # pub fn grayscale(width: i32, height: i32, memory_offset: i32, length: i32) -> *const u8
41
+ #profile.start
42
+ offset = instance.runtime.grayscale_blob($options.width, $options.height, start, data_url.size)
43
+ #result = profile.stop
44
+ rescue => e
45
+ raise "failed to execute grayscale() " + e.message
46
+ end
47
+
48
+ #printer = RubyProf::GraphPrinter.new(result)
49
+ #printer.print(STDOUT, {})
50
+
51
+ len = 0
52
+ until instance.store.memories[0].data[offset.value+len] == "\0"
53
+ len += 1
54
+ end
55
+
56
+ result_b64 = instance.store.memories[0].data[offset.value...(offset.value+len)]
57
+ result = Base64.decode64(result_b64)
58
+
59
+ dest = File.open($options.dest, "w")
60
+ dest.write result
61
+ dest.close
62
+
63
+ puts "created: #{$options.dest}"
64
+
@@ -311,7 +311,7 @@ module Wardite
311
311
  digits = target.memsize
312
312
  count = 0
313
313
  digits.times do |i|
314
- if (target.value & (1 << i)).zero?
314
+ if (target.value & (1 << i)).nonzero?
315
315
  count += 1
316
316
  end
317
317
  end
@@ -347,7 +347,13 @@ module Wardite
347
347
  if !right.is_a?(I32) || !left.is_a?(I32)
348
348
  raise EvalError, "maybe empty or invalid stack"
349
349
  end
350
- runtime.stack.push(I32(left.value_s / right.value_s))
350
+ result = left.value_s / right.value_s.to_f
351
+ iresult = (result >= 0 ? result.floor : result.ceil).to_i
352
+ if iresult >= (1 << (left.memsize - 1))
353
+ raise IntegerOverflow, "integer overflow"
354
+ end
355
+
356
+ runtime.stack.push(I32(iresult))
351
357
 
352
358
 
353
359
  when :i32_div_u
@@ -363,7 +369,13 @@ module Wardite
363
369
  if !right.is_a?(I32) || !left.is_a?(I32)
364
370
  raise EvalError, "maybe empty or invalid stack"
365
371
  end
366
- runtime.stack.push(I32(left.value_s % right.value_s))
372
+ result = left.value_s % right.value_s
373
+ if result > 0 && left.value_s < 0
374
+ result = result - right.value_s
375
+ elsif result < 0 && left.value_s > 0
376
+ result = result - right.value_s
377
+ end
378
+ runtime.stack.push(I32(result))
367
379
 
368
380
 
369
381
  when :i32_rem_u
@@ -403,8 +415,8 @@ module Wardite
403
415
  if !right.is_a?(I32) || !left.is_a?(I32)
404
416
  raise EvalError, "maybe empty or invalid stack"
405
417
  end
406
- value = left.value << right.value
407
- value %= (1 << right.memsize)
418
+ value = left.value << (right.value % right.memsize)
419
+ value %= 1 << right.memsize
408
420
 
409
421
  runtime.stack.push(I32(value))
410
422
 
@@ -414,7 +426,7 @@ module Wardite
414
426
  if !right.is_a?(I32) || !left.is_a?(I32)
415
427
  raise EvalError, "maybe empty or invalid stack"
416
428
  end
417
- value = left.value_s >> right.value
429
+ value = left.value_s >> (right.value % right.memsize)
418
430
  runtime.stack.push(I32(value))
419
431
 
420
432
 
@@ -423,7 +435,7 @@ module Wardite
423
435
  if !right.is_a?(I32) || !left.is_a?(I32)
424
436
  raise EvalError, "maybe empty or invalid stack"
425
437
  end
426
- value = left.value >> right.value
438
+ value = left.value >> (right.value % right.memsize)
427
439
  runtime.stack.push(I32(value))
428
440
 
429
441
 
@@ -432,9 +444,10 @@ module Wardite
432
444
  if !right.is_a?(I32) || !left.is_a?(I32)
433
445
  raise EvalError, "maybe empty or invalid stack"
434
446
  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))
447
+ k = (right.value % right.memsize)
448
+ rotated = left.value << k
449
+ rest = left.value & (I32::I32_MAX << (right.memsize - k))
450
+ value = rotated | (rest >> (right.memsize - k))
438
451
  runtime.stack.push(I32(value))
439
452
 
440
453
 
@@ -443,9 +456,10 @@ module Wardite
443
456
  if !right.is_a?(I32) || !left.is_a?(I32)
444
457
  raise EvalError, "maybe empty or invalid stack"
445
458
  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))
459
+ k = (right.value % right.memsize)
460
+ rotated = left.value >> k
461
+ rest = left.value & (I32::I32_MAX >> (right.memsize - k))
462
+ value = rotated | (rest << (right.memsize - k))
449
463
  runtime.stack.push(I32(value))
450
464
 
451
465
 
@@ -368,7 +368,7 @@ module Wardite
368
368
  digits = target.memsize
369
369
  count = 0
370
370
  digits.times do |i|
371
- if (target.value & (1 << i)).zero?
371
+ if (target.value & (1 << i)).nonzero?
372
372
  count += 1
373
373
  end
374
374
  end
@@ -404,7 +404,13 @@ module Wardite
404
404
  if !right.is_a?(I64) || !left.is_a?(I64)
405
405
  raise EvalError, "maybe empty or invalid stack"
406
406
  end
407
- runtime.stack.push(I64(left.value_s / right.value_s))
407
+ result = left.value_s / right.value_s.to_f
408
+ iresult = (result >= 0 ? result.floor : result.ceil).to_i
409
+ if iresult >= (1 << (left.memsize - 1))
410
+ raise IntegerOverflow, "integer overflow"
411
+ end
412
+
413
+ runtime.stack.push(I64(iresult))
408
414
 
409
415
 
410
416
  when :i64_div_u
@@ -420,7 +426,13 @@ module Wardite
420
426
  if !right.is_a?(I64) || !left.is_a?(I64)
421
427
  raise EvalError, "maybe empty or invalid stack"
422
428
  end
423
- runtime.stack.push(I64(left.value_s % right.value_s))
429
+ result = left.value_s % right.value_s
430
+ if result > 0 && left.value_s < 0
431
+ result = result - right.value_s
432
+ elsif result < 0 && left.value_s > 0
433
+ result = result - right.value_s
434
+ end
435
+ runtime.stack.push(I64(result))
424
436
 
425
437
 
426
438
  when :i64_rem_u
@@ -460,8 +472,8 @@ module Wardite
460
472
  if !right.is_a?(I64) || !left.is_a?(I64)
461
473
  raise EvalError, "maybe empty or invalid stack"
462
474
  end
463
- value = left.value << right.value
464
- value %= (1 << right.memsize)
475
+ value = left.value << (right.value % right.memsize)
476
+ value %= 1 << right.memsize
465
477
 
466
478
  runtime.stack.push(I64(value))
467
479
 
@@ -471,7 +483,7 @@ module Wardite
471
483
  if !right.is_a?(I64) || !left.is_a?(I64)
472
484
  raise EvalError, "maybe empty or invalid stack"
473
485
  end
474
- value = left.value_s >> right.value
486
+ value = left.value_s >> (right.value % right.memsize)
475
487
  runtime.stack.push(I64(value))
476
488
 
477
489
 
@@ -480,7 +492,7 @@ module Wardite
480
492
  if !right.is_a?(I64) || !left.is_a?(I64)
481
493
  raise EvalError, "maybe empty or invalid stack"
482
494
  end
483
- value = left.value >> right.value
495
+ value = left.value >> (right.value % right.memsize)
484
496
  runtime.stack.push(I64(value))
485
497
 
486
498
 
@@ -489,9 +501,10 @@ module Wardite
489
501
  if !right.is_a?(I64) || !left.is_a?(I64)
490
502
  raise EvalError, "maybe empty or invalid stack"
491
503
  end
492
- rotated = left.value << right.value
493
- rest = left.value & (I64::I64_MAX << (right.memsize - right.value))
494
- value = rotated | (rest >> (right.memsize - right.value))
504
+ k = (right.value % right.memsize)
505
+ rotated = left.value << k
506
+ rest = left.value & (I64::I64_MAX << (right.memsize - k))
507
+ value = rotated | (rest >> (right.memsize - k))
495
508
  runtime.stack.push(I64(value))
496
509
 
497
510
 
@@ -500,9 +513,10 @@ module Wardite
500
513
  if !right.is_a?(I64) || !left.is_a?(I64)
501
514
  raise EvalError, "maybe empty or invalid stack"
502
515
  end
503
- rotated = left.value >> right.value
504
- rest = left.value & (I64::I64_MAX >> (right.memsize - right.value))
505
- value = rotated | (rest << (right.memsize - right.value))
516
+ k = (right.value % right.memsize)
517
+ rotated = left.value >> k
518
+ rest = left.value & (I64::I64_MAX >> (right.memsize - k))
519
+ value = rotated | (rest << (right.memsize - k))
506
520
  runtime.stack.push(I64(value))
507
521
 
508
522
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+ module Wardite
4
+ # basic error class.
5
+ class WebAssemblyError < StandardError
6
+ end
7
+
8
+ class IntegerOverflow < WebAssemblyError; end
9
+ end
@@ -78,6 +78,8 @@ module Wardite
78
78
  # TODO: add types of potential operands
79
79
  attr_accessor :operand #: Array[operandItem]
80
80
 
81
+ attr_accessor :meta #: Hash[Symbol, Integer]
82
+
81
83
  # @rbs namespace: Symbol
82
84
  # @rbs code: Symbol
83
85
  # @rbs operand: Array[operandItem]
@@ -85,6 +87,7 @@ module Wardite
85
87
  @namespace = namespace
86
88
  @code = code
87
89
  @operand = operand
90
+ @meta = {}
88
91
  end
89
92
 
90
93
  # @rbs chr: String
data/lib/wardite/load.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # rbs_inline: enabled
2
+ require "wardite/revisitor"
3
+
2
4
  module Wardite
3
5
  class Section
4
6
  attr_accessor :name #: String
@@ -593,10 +595,13 @@ module Wardite
593
595
  locals_type << Op.i2type(value_type || -1)
594
596
  end
595
597
  body = code_body(cbuf)
598
+ revisitor = Revisitor.new(body)
599
+ revisitor.revisit!
600
+
596
601
  dest.func_codes << CodeSection::CodeBody.new do |b|
597
602
  b.locals_count = locals_count
598
603
  b.locals_type = locals_type
599
- b.body = body
604
+ b.body = revisitor.ops
600
605
  end
601
606
  end
602
607
  dest
@@ -0,0 +1,92 @@
1
+ # rbs_inline: enabled
2
+ module Wardite
3
+ class Revisitor
4
+ attr_accessor :ops #: Array[Op]
5
+
6
+ # @rbs ops: Array[Op]
7
+ # @rbs return: void
8
+ def initialize(ops)
9
+ @ops = ops
10
+ end
11
+
12
+ # @rbs return: void
13
+ def revisit!
14
+ @ops.each_with_index do |op, idx|
15
+ case op.code
16
+ when :block
17
+ next_pc = fetch_ops_while_end(idx)
18
+ op.meta[:end_pos] = next_pc
19
+
20
+ when :loop
21
+ next_pc = fetch_ops_while_end(idx)
22
+ op.meta[:end_pos] = next_pc
23
+
24
+ when :if
25
+ next_pc = fetch_ops_while_end(idx)
26
+ else_pc = fetch_ops_while_else_or_end(idx)
27
+ op.meta[:end_pos] = next_pc
28
+ op.meta[:else_pos] = else_pc
29
+ end
30
+ end
31
+ end
32
+
33
+ # @rbs pc_start: Integer
34
+ # @rbs return: Integer
35
+ # @rbs return: void
36
+ def fetch_ops_while_else_or_end(pc_start)
37
+ cursor = pc_start
38
+ depth = 0
39
+ loop {
40
+ cursor += 1
41
+ inst = @ops[cursor]
42
+ case inst&.code
43
+ when nil
44
+ raise EvalError, "end op not found"
45
+ when :if
46
+ depth += 1
47
+ when :else
48
+ if depth == 0
49
+ return cursor
50
+ end
51
+ # do not touch depth
52
+ when :end
53
+ if depth == 0
54
+ return cursor
55
+ else
56
+ depth -= 1
57
+ end
58
+ else
59
+ # nop
60
+ end
61
+ }
62
+ raise "not found corresponding end"
63
+ end
64
+
65
+ # @rbs pc_start: Integer
66
+ # @rbs return: Integer
67
+ # @rbs return: void
68
+ def fetch_ops_while_end(pc_start)
69
+ cursor = pc_start
70
+ depth = 0
71
+ loop {
72
+ cursor += 1
73
+ inst = @ops[cursor]
74
+ case inst&.code
75
+ when nil
76
+ raise EvalError, "end op not found"
77
+ when :if, :block, :loop
78
+ depth += 1
79
+ when :end
80
+ if depth == 0
81
+ return cursor
82
+ else
83
+ depth -= 1
84
+ end
85
+ else
86
+ # nop
87
+ end
88
+ }
89
+ raise "not found corresponding end"
90
+ end
91
+ end
92
+ end
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Wardite
5
- VERSION = "0.4.3" #: String
5
+ VERSION = "0.5.1" #: String
6
6
  end
data/lib/wardite.rb CHANGED
@@ -7,6 +7,7 @@ require_relative "wardite/const"
7
7
  require_relative "wardite/instruction"
8
8
  require_relative "wardite/value"
9
9
  require_relative "wardite/load"
10
+ require_relative "wardite/errors"
10
11
 
11
12
  module Wardite
12
13
  module Evaluator
@@ -472,7 +473,7 @@ module Wardite
472
473
  when :block
473
474
  block = insn.operand[0]
474
475
  raise EvalError, "block op without block" if !block.is_a?(Block)
475
- next_pc = fetch_ops_while_end(frame.body, frame.pc)
476
+ next_pc = insn.meta[:end_pos]
476
477
  label = Label.new(:block, next_pc, stack.size, block.result_size)
477
478
  frame.labels.push(label)
478
479
 
@@ -480,19 +481,19 @@ module Wardite
480
481
  block = insn.operand[0]
481
482
  raise EvalError, "loop op without block" if !block.is_a?(Block)
482
483
  start = frame.pc
483
- end_pc = fetch_ops_while_end(frame.body, frame.pc)
484
- label = Label.new(:loop, end_pc, stack.size, block.result_size, start)
484
+ next_pc = insn.meta[:end_pos]
485
+ label = Label.new(:loop, next_pc, stack.size, block.result_size, start)
485
486
  frame.labels.push(label)
486
487
 
487
488
  when :if
488
489
  block = insn.operand[0]
489
490
  raise EvalError, "if op without block" if !block.is_a?(Block)
490
- cond = stack.pop
491
+ cond = stack.pop
491
492
  raise EvalError, "cond not found" if !cond.is_a?(I32)
492
- next_pc = fetch_ops_while_end(frame.body, frame.pc)
493
+ next_pc = insn.meta[:end_pos]
493
494
 
494
495
  if cond.value.zero?
495
- frame.pc = fetch_ops_while_else_or_end(frame.body, frame.pc)
496
+ frame.pc = insn.meta[:else_pos]
496
497
  end
497
498
 
498
499
  if frame.pc == next_pc
@@ -739,38 +740,6 @@ module Wardite
739
740
  raise e
740
741
  end
741
742
 
742
- # @rbs ops: Array[Op]
743
- # @rbs pc_start: Integer
744
- # @rbs return: Integer
745
- def fetch_ops_while_else_or_end(ops, pc_start)
746
- cursor = pc_start
747
- depth = 0
748
- loop {
749
- cursor += 1
750
- inst = ops[cursor]
751
- case inst&.code
752
- when nil
753
- raise EvalError, "end op not found"
754
- when :if
755
- depth += 1
756
- when :else
757
- if depth == 0
758
- return cursor
759
- end
760
- # do not touch depth
761
- when :end
762
- if depth == 0
763
- return cursor
764
- else
765
- depth -= 1
766
- end
767
- else
768
- # nop
769
- end
770
- }
771
- raise "[BUG] unreachable"
772
- end
773
-
774
743
  # @rbs labels: Array[Label]
775
744
  # @rbs stack: Array[wasmValue]
776
745
  # @rbs level: Integer
@@ -796,33 +765,6 @@ module Wardite
796
765
  pc
797
766
  end
798
767
 
799
- # @rbs ops: Array[Op]
800
- # @rbs pc_start: Integer
801
- # @rbs return: Integer
802
- def fetch_ops_while_end(ops, pc_start)
803
- cursor = pc_start
804
- depth = 0
805
- loop {
806
- cursor += 1
807
- inst = ops[cursor]
808
- case inst&.code
809
- when nil
810
- raise EvalError, "end op not found"
811
- when :if, :block, :loop
812
- depth += 1
813
- when :end
814
- if depth == 0
815
- return cursor
816
- else
817
- depth -= 1
818
- end
819
- else
820
- # nop
821
- end
822
- }
823
- raise "[BUG] unreachable"
824
- end
825
-
826
768
  # unwind the stack and put return value if exists
827
769
  # @rbs sp: Integer
828
770
  # @rbs arity: Integer
@@ -1119,6 +1061,7 @@ module Wardite
1119
1061
  end
1120
1062
 
1121
1063
  @data += String.new("\0" * (delta * 64 * 1024))
1064
+ self.current = newsize
1122
1065
  prev
1123
1066
  end
1124
1067
 
data/scripts/gen_alu.rb CHANGED
@@ -480,7 +480,7 @@ module GenAlu
480
480
  digits = target.memsize
481
481
  count = 0
482
482
  digits.times do |i|
483
- if (target.value & (1 << i)).zero?
483
+ if (target.value & (1 << i)).nonzero?
484
484
  count += 1
485
485
  end
486
486
  end
@@ -520,7 +520,13 @@ module GenAlu
520
520
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
521
521
  raise EvalError, "maybe empty or invalid stack"
522
522
  end
523
- runtime.stack.push(${CLASS}(left.value_s / right.value_s))
523
+ result = left.value_s / right.value_s.to_f
524
+ iresult = (result >= 0 ? result.floor : result.ceil).to_i
525
+ if iresult >= (1 << (left.memsize - 1))
526
+ raise IntegerOverflow, "integer overflow"
527
+ end
528
+
529
+ runtime.stack.push(${CLASS}(iresult))
524
530
  RUBY
525
531
 
526
532
  div_u: <<~RUBY,
@@ -547,7 +553,13 @@ module GenAlu
547
553
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
548
554
  raise EvalError, "maybe empty or invalid stack"
549
555
  end
550
- runtime.stack.push(${CLASS}(left.value_s % right.value_s))
556
+ result = left.value_s % right.value_s
557
+ if result > 0 && left.value_s < 0
558
+ result = result - right.value_s
559
+ elsif result < 0 && left.value_s > 0
560
+ result = result - right.value_s
561
+ end
562
+ runtime.stack.push(${CLASS}(result))
551
563
  RUBY
552
564
 
553
565
  rem_u: <<~RUBY,
@@ -592,8 +604,8 @@ module GenAlu
592
604
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
593
605
  raise EvalError, "maybe empty or invalid stack"
594
606
  end
595
- value = left.value << right.value
596
- value %= (1 << right.memsize)
607
+ value = left.value << (right.value % right.memsize)
608
+ value %= 1 << right.memsize
597
609
 
598
610
  runtime.stack.push(${CLASS}(value))
599
611
  RUBY
@@ -604,7 +616,7 @@ module GenAlu
604
616
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
605
617
  raise EvalError, "maybe empty or invalid stack"
606
618
  end
607
- value = left.value_s >> right.value
619
+ value = left.value_s >> (right.value % right.memsize)
608
620
  runtime.stack.push(${CLASS}(value))
609
621
  RUBY
610
622
 
@@ -614,7 +626,7 @@ module GenAlu
614
626
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
615
627
  raise EvalError, "maybe empty or invalid stack"
616
628
  end
617
- value = left.value >> right.value
629
+ value = left.value >> (right.value % right.memsize)
618
630
  runtime.stack.push(${CLASS}(value))
619
631
  RUBY
620
632
 
@@ -624,9 +636,10 @@ module GenAlu
624
636
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
625
637
  raise EvalError, "maybe empty or invalid stack"
626
638
  end
627
- rotated = left.value << right.value
628
- rest = left.value & (${CLASS}::${CLASS}_MAX << (right.memsize - right.value))
629
- value = rotated | (rest >> (right.memsize - right.value))
639
+ k = (right.value % right.memsize)
640
+ rotated = left.value << k
641
+ rest = left.value & (${CLASS}::${CLASS}_MAX << (right.memsize - k))
642
+ value = rotated | (rest >> (right.memsize - k))
630
643
  runtime.stack.push(${CLASS}(value))
631
644
  RUBY
632
645
 
@@ -636,9 +649,10 @@ module GenAlu
636
649
  if !right.is_a?(${CLASS}) || !left.is_a?(${CLASS})
637
650
  raise EvalError, "maybe empty or invalid stack"
638
651
  end
639
- rotated = left.value >> right.value
640
- rest = left.value & (${CLASS}::${CLASS}_MAX >> (right.memsize - right.value))
641
- value = rotated | (rest << (right.memsize - right.value))
652
+ k = (right.value % right.memsize)
653
+ rotated = left.value >> k
654
+ rest = left.value & (${CLASS}::${CLASS}_MAX >> (right.memsize - k))
655
+ value = rotated | (rest << (right.memsize - k))
642
656
  runtime.stack.push(${CLASS}(value))
643
657
  RUBY
644
658
 
@@ -0,0 +1,12 @@
1
+ # Generated from lib/wardite/errors.rb with RBS::Inline
2
+
3
+ # frozen_string_literal: true
4
+ # rbs_inline: enabled
5
+ module Wardite
6
+ # basic error class.
7
+ class WebAssemblyError < StandardError
8
+ end
9
+
10
+ class IntegerOverflow < WebAssemblyError
11
+ end
12
+ end
@@ -22,6 +22,8 @@ module Wardite
22
22
  # TODO: add types of potential operands
23
23
  attr_accessor operand: Array[operandItem]
24
24
 
25
+ attr_accessor meta: Hash[Symbol, Integer]
26
+
25
27
  # @rbs namespace: Symbol
26
28
  # @rbs code: Symbol
27
29
  # @rbs operand: Array[operandItem]
@@ -1,6 +1,5 @@
1
1
  # Generated from lib/wardite/load.rb with RBS::Inline
2
2
 
3
- # rbs_inline: enabled
4
3
  module Wardite
5
4
  class Section
6
5
  attr_accessor name: String
@@ -0,0 +1,25 @@
1
+ # Generated from lib/wardite/revisitor.rb with RBS::Inline
2
+
3
+ # rbs_inline: enabled
4
+ module Wardite
5
+ class Revisitor
6
+ attr_accessor ops: Array[Op]
7
+
8
+ # @rbs ops: Array[Op]
9
+ # @rbs return: void
10
+ def initialize: (Array[Op] ops) -> void
11
+
12
+ # @rbs return: void
13
+ def revisit!: () -> void
14
+
15
+ # @rbs pc_start: Integer
16
+ # @rbs return: Integer
17
+ # @rbs return: void
18
+ def fetch_ops_while_else_or_end: (Integer pc_start) -> Integer
19
+
20
+ # @rbs pc_start: Integer
21
+ # @rbs return: Integer
22
+ # @rbs return: void
23
+ def fetch_ops_while_end: (Integer pc_start) -> Integer
24
+ end
25
+ end
@@ -115,22 +115,12 @@ module Wardite
115
115
  # @rbs return: void
116
116
  def eval_insn: (Frame frame, Op insn) -> void
117
117
 
118
- # @rbs ops: Array[Op]
119
- # @rbs pc_start: Integer
120
- # @rbs return: Integer
121
- def fetch_ops_while_else_or_end: (Array[Op] ops, Integer pc_start) -> Integer
122
-
123
118
  # @rbs labels: Array[Label]
124
119
  # @rbs stack: Array[wasmValue]
125
120
  # @rbs level: Integer
126
121
  # @rbs return: Integer
127
122
  def do_branch: (Array[Label] labels, Array[wasmValue] stack, Integer level) -> Integer
128
123
 
129
- # @rbs ops: Array[Op]
130
- # @rbs pc_start: Integer
131
- # @rbs return: Integer
132
- def fetch_ops_while_end: (Array[Op] ops, Integer pc_start) -> Integer
133
-
134
124
  # unwind the stack and put return value if exists
135
125
  # @rbs sp: Integer
136
126
  # @rbs arity: Integer
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wardite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio Kondo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-17 00:00:00.000000000 Z
11
+ date: 2024-11-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A pure-ruby webassembly runtime
14
14
  email:
@@ -31,6 +31,7 @@ files:
31
31
  - examples/fib.wat
32
32
  - examples/fib2.wat
33
33
  - examples/global.wat
34
+ - examples/grayscale.rb
34
35
  - examples/helloworld.wat
35
36
  - examples/i32_const.wat
36
37
  - examples/i32_store.wat
@@ -49,9 +50,11 @@ files:
49
50
  - lib/wardite/alu_i64.generated.rb
50
51
  - lib/wardite/const.rb
51
52
  - lib/wardite/convert.generated.rb
53
+ - lib/wardite/errors.rb
52
54
  - lib/wardite/instruction.rb
53
55
  - lib/wardite/leb128.rb
54
56
  - lib/wardite/load.rb
57
+ - lib/wardite/revisitor.rb
55
58
  - lib/wardite/value.rb
56
59
  - lib/wardite/version.rb
57
60
  - lib/wardite/wasi.rb
@@ -66,9 +69,11 @@ files:
66
69
  - sig/generated/wardite/alu_i64.generated.rbs
67
70
  - sig/generated/wardite/const.rbs
68
71
  - sig/generated/wardite/convert.generated.rbs
72
+ - sig/generated/wardite/errors.rbs
69
73
  - sig/generated/wardite/instruction.rbs
70
74
  - sig/generated/wardite/leb128.rbs
71
75
  - sig/generated/wardite/load.rbs
76
+ - sig/generated/wardite/revisitor.rbs
72
77
  - sig/generated/wardite/value.rbs
73
78
  - sig/generated/wardite/version.rbs
74
79
  - sig/generated/wardite/wasi.rbs