wardite 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +163 -0
- data/Steepfile +1 -0
- data/examples/consts.wat +12 -0
- data/lib/wardite/alu_f32.generated.rb +250 -0
- data/lib/wardite/alu_f64.generated.rb +250 -0
- data/lib/wardite/alu_i32.generated.rb +398 -18
- data/lib/wardite/alu_i64.generated.rb +514 -0
- data/lib/wardite/convert.generated.rb +234 -0
- data/lib/wardite/instruction.rb +62 -31
- data/lib/wardite/value.rb +576 -31
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite/wasi.rb +1 -1
- data/lib/wardite.rb +127 -77
- data/scripts/gen_alu.rb +653 -27
- data/scripts/gen_conv.rb +76 -0
- data/scripts/templates/conv_module.rb.tmpl +18 -0
- data/sig/generated/wardite/alu_f32.generated.rbs +11 -0
- data/sig/generated/wardite/alu_f64.generated.rbs +11 -0
- data/sig/generated/wardite/alu_i64.generated.rbs +11 -0
- data/sig/generated/wardite/convert.generated.rbs +11 -0
- data/sig/generated/wardite/instruction.rbs +6 -0
- data/sig/generated/wardite/value.rbs +263 -19
- data/sig/generated/wardite.rbs +12 -3
- metadata +13 -2
@@ -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
|
data/lib/wardite/instruction.rb
CHANGED
@@ -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 =
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
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 :
|
75
|
-
[:
|
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
|
[]
|