wardite 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,234 @@
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.convert_eval_insn(runtime, frame, insn)
11
+ case insn.code
12
+
13
+ when :i32_wrap_i64
14
+ from = runtime.stack.pop
15
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
16
+ to = from.wrap(to: :i32)
17
+ raise EvalError, "failed to convert type" if !to.is_a?(I32)
18
+ runtime.stack.push(to)
19
+
20
+
21
+ when :i32_trunc_f32_s
22
+ from = runtime.stack.pop
23
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
24
+ to = from.trunc_s(to: :i32)
25
+ raise EvalError, "failed to convert type" if !to.is_a?(I32)
26
+ runtime.stack.push(to)
27
+
28
+
29
+ when :i32_trunc_f64_s
30
+ from = runtime.stack.pop
31
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
32
+ to = from.trunc_s(to: :i32)
33
+ raise EvalError, "failed to convert type" if !to.is_a?(I32)
34
+ runtime.stack.push(to)
35
+
36
+
37
+ when :i32_trunc_f32_u
38
+ from = runtime.stack.pop
39
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
40
+ to = from.trunc_u(to: :i32)
41
+ raise EvalError, "failed to convert type" if !to.is_a?(I32)
42
+ runtime.stack.push(to)
43
+
44
+
45
+ when :i32_trunc_f64_u
46
+ from = runtime.stack.pop
47
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
48
+ to = from.trunc_u(to: :i32)
49
+ raise EvalError, "failed to convert type" if !to.is_a?(I32)
50
+ runtime.stack.push(to)
51
+
52
+
53
+ when :i32_reinterpret_f32
54
+ from = runtime.stack.pop
55
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
56
+ to = from.reinterpret(to: :i32)
57
+ raise EvalError, "failed to convert type" if !to.is_a?(I32)
58
+ runtime.stack.push(to)
59
+
60
+
61
+ when :i64_extend_i32_s
62
+ from = runtime.stack.pop
63
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
64
+ to = from.extend_s(to: :i64)
65
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
66
+ runtime.stack.push(to)
67
+
68
+
69
+ when :i64_extend_i64_s
70
+ from = runtime.stack.pop
71
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
72
+ to = from.extend_s(to: :i64)
73
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
74
+ runtime.stack.push(to)
75
+
76
+
77
+ when :i64_extend_i32_u
78
+ from = runtime.stack.pop
79
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
80
+ to = from.extend_u(to: :i64)
81
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
82
+ runtime.stack.push(to)
83
+
84
+
85
+ when :i64_extend_i64_u
86
+ from = runtime.stack.pop
87
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
88
+ to = from.extend_u(to: :i64)
89
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
90
+ runtime.stack.push(to)
91
+
92
+
93
+ when :i64_trunc_f32_s
94
+ from = runtime.stack.pop
95
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
96
+ to = from.trunc_s(to: :i64)
97
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
98
+ runtime.stack.push(to)
99
+
100
+
101
+ when :i64_trunc_f64_s
102
+ from = runtime.stack.pop
103
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
104
+ to = from.trunc_s(to: :i64)
105
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
106
+ runtime.stack.push(to)
107
+
108
+
109
+ when :i64_trunc_f32_u
110
+ from = runtime.stack.pop
111
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
112
+ to = from.trunc_u(to: :i64)
113
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
114
+ runtime.stack.push(to)
115
+
116
+
117
+ when :i64_trunc_f64_u
118
+ from = runtime.stack.pop
119
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
120
+ to = from.trunc_u(to: :i64)
121
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
122
+ runtime.stack.push(to)
123
+
124
+
125
+ when :i64_reinterpret_f64
126
+ from = runtime.stack.pop
127
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
128
+ to = from.reinterpret(to: :i64)
129
+ raise EvalError, "failed to convert type" if !to.is_a?(I64)
130
+ runtime.stack.push(to)
131
+
132
+
133
+ when :f32_convert_i32_s
134
+ from = runtime.stack.pop
135
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
136
+ to = from.convert_s(to: :f32)
137
+ raise EvalError, "failed to convert type" if !to.is_a?(F32)
138
+ runtime.stack.push(to)
139
+
140
+
141
+ when :f32_convert_i64_s
142
+ from = runtime.stack.pop
143
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
144
+ to = from.convert_s(to: :f32)
145
+ raise EvalError, "failed to convert type" if !to.is_a?(F32)
146
+ runtime.stack.push(to)
147
+
148
+
149
+ when :f32_convert_i32_u
150
+ from = runtime.stack.pop
151
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
152
+ to = from.convert_u(to: :f32)
153
+ raise EvalError, "failed to convert type" if !to.is_a?(F32)
154
+ runtime.stack.push(to)
155
+
156
+
157
+ when :f32_convert_i64_u
158
+ from = runtime.stack.pop
159
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
160
+ to = from.convert_u(to: :f32)
161
+ raise EvalError, "failed to convert type" if !to.is_a?(F32)
162
+ runtime.stack.push(to)
163
+
164
+
165
+ when :f32_demote_f64
166
+ from = runtime.stack.pop
167
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
168
+ to = from.demote(to: :f32)
169
+ raise EvalError, "failed to convert type" if !to.is_a?(F32)
170
+ runtime.stack.push(to)
171
+
172
+
173
+ when :f32_reinterpret_i32
174
+ from = runtime.stack.pop
175
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
176
+ to = from.reinterpret(to: :f32)
177
+ raise EvalError, "failed to convert type" if !to.is_a?(F32)
178
+ runtime.stack.push(to)
179
+
180
+
181
+ when :f64_convert_i32_s
182
+ from = runtime.stack.pop
183
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
184
+ to = from.convert_s(to: :f64)
185
+ raise EvalError, "failed to convert type" if !to.is_a?(F64)
186
+ runtime.stack.push(to)
187
+
188
+
189
+ when :f64_convert_i64_s
190
+ from = runtime.stack.pop
191
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
192
+ to = from.convert_s(to: :f64)
193
+ raise EvalError, "failed to convert type" if !to.is_a?(F64)
194
+ runtime.stack.push(to)
195
+
196
+
197
+ when :f64_convert_i32_u
198
+ from = runtime.stack.pop
199
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
200
+ to = from.convert_u(to: :f64)
201
+ raise EvalError, "failed to convert type" if !to.is_a?(F64)
202
+ runtime.stack.push(to)
203
+
204
+
205
+ when :f64_convert_i64_u
206
+ from = runtime.stack.pop
207
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
208
+ to = from.convert_u(to: :f64)
209
+ raise EvalError, "failed to convert type" if !to.is_a?(F64)
210
+ runtime.stack.push(to)
211
+
212
+
213
+ when :f64_promote_f32
214
+ from = runtime.stack.pop
215
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
216
+ to = from.promote(to: :f64)
217
+ raise EvalError, "failed to convert type" if !to.is_a?(F64)
218
+ runtime.stack.push(to)
219
+
220
+
221
+ when :f64_reinterpret_i64
222
+ from = runtime.stack.pop
223
+ raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I64)
224
+ to = from.reinterpret(to: :f64)
225
+ raise EvalError, "failed to convert type" if !to.is_a?(F64)
226
+ runtime.stack.push(to)
227
+
228
+
229
+ else
230
+ raise "Unknown opcode for namespace #{insn.namespace}: #{insn.code}"
231
+ end
232
+ end
233
+ end
234
+ end
@@ -1,47 +1,84 @@
1
1
  # rbs_inline: enabled
2
+
2
3
  module Wardite
3
4
  class Op
5
+ # @see https://pengowray.github.io/wasm-ops/
6
+ SYMS = %i[
7
+ unreachable nop block loop if else try catch
8
+ throw rethrow throw_ref end br br_if br_table return
9
+ call call_indirect return_call return_call_indirect call_ref return_call_ref __undef__ __undef__
10
+ delegate catch_all drop select select_t __undef__ __undef__ try_table
11
+ local_get local_set local_tee global_get global_set table_get table_set __undef__
12
+ i32_load i64_load f32_load f64_load i32_load8_s i32_load8_u i32_load16_s i32_load16_u
13
+ i64_load8_s i64_load8_u i64_load16_s i64_load16_u i64_load32_s i64_load32_u i32_store i64_store
14
+ f32_store f64_store i32_store8 i32_store16 i64_store8 i64_store16 i64_store32 memory_size
15
+ memory_grow i32_const i64_const f32_const f64_const i32_eqz i32_eq i32_ne
16
+ i32_lts i32_ltu i32_gts i32_gtu i32_les i32_leu i32_ges i32_geu
17
+ i64_eqz i64_eq i64_ne i64_lts i64_ltu i64_gts i64_gtu i64_les
18
+ i64_leu i64_ges i64_geu f32_eq f32_ne f32_lt f32_gt f32_le
19
+ f32_ge f64_eq f64_ne f64_lt f64_gt f64_le f64_ge i32_clz
20
+ i32_ctz i32_popcnt i32_add i32_sub i32_mul i32_div_s i32_div_u i32_rem_s
21
+ i32_rem_u i32_and i32_or i32_xor i32_shl i32_shr_s i32_shr_u i32_rotl
22
+ i32_rotr i64_clz i64_ctz i64_popcnt i64_add i64_sub i64_mul i64_div_s
23
+ i64_div_u i64_rem_s i64_rem_u i64_and i64_or i64_xor i64_shl i64_shr_s
24
+ i64_shr_u i64_rotl i64_rotr f32_abs f32_neg f32_ceil f32_floor f32_trunc
25
+ f32_nearest f32_sqrt f32_add f32_sub f32_mul f32_div f32_min f32_max
26
+ f32_copysign f64_abs f64_neg f64_ceil f64_floor f64_trunc f64_nearest f64_sqrt
27
+ f64_add f64_sub f64_mul f64_div f64_min f64_max f64_copysign i32_wrap_i64
28
+ i32_trunc_f32_s i32_trunc_f32_u i32_trunc_f64_s i32_trunc_f64_u i64_extend_i32_s i64_extend_i32_u i64_trunc_f32_s i64_trunc_f32_u
29
+ i64_trunc_f64_s i64_trunc_f64_u f32_convert_i32_s f32_convert_i32_u f32_convert_i64_s f32_convert_i64_u f32_demote_f64 f64_convert_i32_s
30
+ f64_convert_i32_u f64_convert_i64_s f64_convert_i64_u f64_promote_f32 i32_reinterpret_f32 i64_reinterpret_f64 f32_reinterpret_i32 f64_reinterpret_i64
31
+ __unsuported_from_here_on__
32
+ ] #: Array[Symbol]
33
+
34
+ # @rbs @@table: Hash[Integer, Symbol] | nil
35
+ @@table = nil
36
+
37
+ # @rbs return: Hash[Integer, Symbol]
38
+ def self.table
39
+ @@table if @@table != nil
40
+ @@table = {}.tap do |ha|
41
+ SYMS.each_with_index do |sym, i|
42
+ ha[i] = sym
43
+ end
44
+ end
45
+ @@table
46
+ end
47
+
48
+ attr_accessor :namespace #: Symbol
49
+
4
50
  attr_accessor :code #: Symbol
5
51
 
6
- attr_accessor :operand #: Array[Object]
52
+ # TODO: add types of potential operands
53
+ attr_accessor :operand #: Array[Integer|Float|Block]
7
54
 
55
+ # @rbs namespace: Symbol
8
56
  # @rbs code: Symbol
9
- # @rbs operand: Array[Object]
10
- def initialize(code, operand)
57
+ # @rbs operand: Array[Integer|Float|Block]
58
+ def initialize(namespace, code, operand)
59
+ @namespace = namespace
11
60
  @code = code
12
61
  @operand = operand
13
62
  end
14
63
 
15
64
  # @rbs chr: String
16
- # @rbs return: Symbol
65
+ # @rbs return: [Symbol, Symbol]
17
66
  def self.to_sym(chr)
18
- case chr
19
- when "\u0004"
20
- :if
21
- when "\u000b"
22
- :end
23
- when "\u000f"
24
- :return
25
- when "\u0010"
26
- :call
27
- when "\u0020"
28
- :local_get
29
- when "\u0021"
30
- :local_set
31
- when "\u0036"
32
- :i32_store
33
- when "\u0041"
34
- :i32_const
35
- when "\u0048"
36
- :i32_lts
37
- when "\u004d"
38
- :i32_leu
39
- when "\u006a"
40
- :i32_add
41
- when "\u006b"
42
- :i32_sub
67
+ code = table[chr.ord]
68
+ if ! code
69
+ raise "found unknown code 0x#{chr.ord.to_s(16)}"
70
+ end
71
+ # opcodes equal to or larger than are "convert" ops
72
+ if chr.ord >= 0xa7
73
+ return [:convert, code]
74
+ end
75
+
76
+ prefix = code.to_s.split("_")[0]
77
+ case prefix
78
+ when "i32", "i64", "f32", "f64"
79
+ [prefix.to_sym, code]
43
80
  else
44
- raise NotImplementedError, "unimplemented: #{"%04x" % chr.ord}"
81
+ [:default, code]
45
82
  end
46
83
  end
47
84
 
@@ -49,13 +86,25 @@ module Wardite
49
86
  # @rbs return: Array[Symbol]
50
87
  def self.operand_of(code)
51
88
  case code
52
- when :local_get, :local_set, :call
89
+ when /load/, /store/
90
+ [:u32, :u32]
91
+ when :local_get, :local_set, :local_tee, :global_get, :global_set, :call, :br, :br_if
53
92
  [:u32]
93
+ when :call_indirect
94
+ [:u32, :u8]
95
+ when :br_table
96
+ [:u32_vec, :u32]
54
97
  when :i32_const
55
98
  [:i32]
56
- when :i32_store
57
- [:u32, :u32]
99
+ when :i64_const
100
+ [:i64]
101
+ when :f32_const
102
+ [:f32]
103
+ when :f64_const
104
+ [:f64]
58
105
  when :if
106
+ [:u8_if_block]
107
+ when :block, :loop
59
108
  [:u8_block]
60
109
  else
61
110
  []
@@ -1,6 +1,6 @@
1
1
  # rbs_inline: enabled
2
2
  module Wardite
3
- module Leb128Helpers
3
+ module Leb128Helper
4
4
  # @rbs buf: File|StringIO
5
5
  # @rbs return: Integer
6
6
  def fetch_uleb128(buf)