wardite 0.2.0 → 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
@@ -2,6 +2,49 @@
2
2
 
3
3
  module Wardite
4
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
+
5
48
  attr_accessor :namespace #: Symbol
6
49
 
7
50
  attr_accessor :code #: Symbol
@@ -21,34 +64,10 @@ module Wardite
21
64
  # @rbs chr: String
22
65
  # @rbs return: [Symbol, Symbol]
23
66
  def self.to_sym(chr)
24
- code = case chr
25
- when "\u0004"
26
- :if
27
- when "\u000b"
28
- :end
29
- when "\u000f"
30
- :return
31
- when "\u0010"
32
- :call
33
- when "\u0020"
34
- :local_get
35
- when "\u0021"
36
- :local_set
37
- when "\u0036"
38
- :i32_store
39
- when "\u0041"
40
- :i32_const
41
- when "\u0048"
42
- :i32_lts
43
- when "\u004d"
44
- :i32_leu
45
- when "\u006a"
46
- :i32_add
47
- when "\u006b"
48
- :i32_sub
49
- else
50
- raise NotImplementedError, "unimplemented: #{"%04x" % chr.ord}"
51
- end
67
+ code = table[chr.ord]
68
+ if ! code
69
+ raise "found unknown code 0x#{chr.ord.to_s(16)}"
70
+ end
52
71
  # opcodes equal to or larger than are "convert" ops
53
72
  if chr.ord >= 0xa7
54
73
  return [:convert, code]
@@ -67,13 +86,25 @@ module Wardite
67
86
  # @rbs return: Array[Symbol]
68
87
  def self.operand_of(code)
69
88
  case code
70
- 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
71
92
  [:u32]
93
+ when :call_indirect
94
+ [:u32, :u8]
95
+ when :br_table
96
+ [:u32_vec, :u32]
72
97
  when :i32_const
73
98
  [:i32]
74
- when :i32_store
75
- [:u32, :u32]
99
+ when :i64_const
100
+ [:i64]
101
+ when :f32_const
102
+ [:f32]
103
+ when :f64_const
104
+ [:f64]
76
105
  when :if
106
+ [:u8_if_block]
107
+ when :block, :loop
77
108
  [:u8_block]
78
109
  else
79
110
  []