wardite 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3ca81e45a3da7f90566d465d5248bcac03981953e97c81681de900851348407
4
- data.tar.gz: 2b0952f92a92bce4d54283868fd2565b9dbaa178cc1187b2a7f6feca6225fe57
3
+ metadata.gz: 89b6c42e1a3f16c39c214eb127c5b87966c0d2933257a1da7fdc96236c6a0f9b
4
+ data.tar.gz: 321d62cdddc61c8a342b966b3e4d7b6c01ffbbcb5788a6787fd3490ba96b1430
5
5
  SHA512:
6
- metadata.gz: 8a4db779ed117465fb2c981c0b9da39dcdd001e60abf00262d04353449b5b72ad433949d6c640458fe2b61b503e84180dbf3c7709d791b48f7ed2a5ad9dbe372
7
- data.tar.gz: 7d00f04205f6ef10b21dee7067adf1f480a529cea4bf0caa404fd888547f101f3908f54863262333e2b363d2d17b28b4899ff12ddc5e226958eda975354fd954
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
+
@@ -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.5.0" #: String
5
+ VERSION = "0.5.1" #: String
6
6
  end
data/lib/wardite.rb CHANGED
@@ -473,7 +473,7 @@ module Wardite
473
473
  when :block
474
474
  block = insn.operand[0]
475
475
  raise EvalError, "block op without block" if !block.is_a?(Block)
476
- next_pc = fetch_ops_while_end(frame.body, frame.pc)
476
+ next_pc = insn.meta[:end_pos]
477
477
  label = Label.new(:block, next_pc, stack.size, block.result_size)
478
478
  frame.labels.push(label)
479
479
 
@@ -481,19 +481,19 @@ module Wardite
481
481
  block = insn.operand[0]
482
482
  raise EvalError, "loop op without block" if !block.is_a?(Block)
483
483
  start = frame.pc
484
- end_pc = fetch_ops_while_end(frame.body, frame.pc)
485
- 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)
486
486
  frame.labels.push(label)
487
487
 
488
488
  when :if
489
489
  block = insn.operand[0]
490
490
  raise EvalError, "if op without block" if !block.is_a?(Block)
491
- cond = stack.pop
491
+ cond = stack.pop
492
492
  raise EvalError, "cond not found" if !cond.is_a?(I32)
493
- next_pc = fetch_ops_while_end(frame.body, frame.pc)
493
+ next_pc = insn.meta[:end_pos]
494
494
 
495
495
  if cond.value.zero?
496
- frame.pc = fetch_ops_while_else_or_end(frame.body, frame.pc)
496
+ frame.pc = insn.meta[:else_pos]
497
497
  end
498
498
 
499
499
  if frame.pc == next_pc
@@ -740,38 +740,6 @@ module Wardite
740
740
  raise e
741
741
  end
742
742
 
743
- # @rbs ops: Array[Op]
744
- # @rbs pc_start: Integer
745
- # @rbs return: Integer
746
- def fetch_ops_while_else_or_end(ops, pc_start)
747
- cursor = pc_start
748
- depth = 0
749
- loop {
750
- cursor += 1
751
- inst = ops[cursor]
752
- case inst&.code
753
- when nil
754
- raise EvalError, "end op not found"
755
- when :if
756
- depth += 1
757
- when :else
758
- if depth == 0
759
- return cursor
760
- end
761
- # do not touch depth
762
- when :end
763
- if depth == 0
764
- return cursor
765
- else
766
- depth -= 1
767
- end
768
- else
769
- # nop
770
- end
771
- }
772
- raise "[BUG] unreachable"
773
- end
774
-
775
743
  # @rbs labels: Array[Label]
776
744
  # @rbs stack: Array[wasmValue]
777
745
  # @rbs level: Integer
@@ -797,33 +765,6 @@ module Wardite
797
765
  pc
798
766
  end
799
767
 
800
- # @rbs ops: Array[Op]
801
- # @rbs pc_start: Integer
802
- # @rbs return: Integer
803
- def fetch_ops_while_end(ops, pc_start)
804
- cursor = pc_start
805
- depth = 0
806
- loop {
807
- cursor += 1
808
- inst = ops[cursor]
809
- case inst&.code
810
- when nil
811
- raise EvalError, "end op not found"
812
- when :if, :block, :loop
813
- depth += 1
814
- when :end
815
- if depth == 0
816
- return cursor
817
- else
818
- depth -= 1
819
- end
820
- else
821
- # nop
822
- end
823
- }
824
- raise "[BUG] unreachable"
825
- end
826
-
827
768
  # unwind the stack and put return value if exists
828
769
  # @rbs sp: Integer
829
770
  # @rbs arity: Integer
@@ -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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wardite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio Kondo
@@ -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
@@ -53,6 +54,7 @@ files:
53
54
  - lib/wardite/instruction.rb
54
55
  - lib/wardite/leb128.rb
55
56
  - lib/wardite/load.rb
57
+ - lib/wardite/revisitor.rb
56
58
  - lib/wardite/value.rb
57
59
  - lib/wardite/version.rb
58
60
  - lib/wardite/wasi.rb
@@ -71,6 +73,7 @@ files:
71
73
  - sig/generated/wardite/instruction.rbs
72
74
  - sig/generated/wardite/leb128.rbs
73
75
  - sig/generated/wardite/load.rbs
76
+ - sig/generated/wardite/revisitor.rbs
74
77
  - sig/generated/wardite/value.rbs
75
78
  - sig/generated/wardite/version.rbs
76
79
  - sig/generated/wardite/wasi.rbs