wardite 0.2.0 → 0.2.2

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: 8e33fd39e5cc58e9ec6071c4a74d5cbe872d68355657dd1adfdf375d74cf03b9
4
- data.tar.gz: cee2e80f2dda3a2366450cf9b2d6656b172faa41b69eba39c03610b8a3c8d38b
3
+ metadata.gz: 932c8c0c36490c2b84b652ee4b43682ee0218c3d6ed4164685e5066b45e79e60
4
+ data.tar.gz: d185d75762ac744752fede64fe6fd766a4639105697af520eb01b802ae7bd4a2
5
5
  SHA512:
6
- metadata.gz: bfabd5ef113b7ebdc5e7aa5059eed7984e5f38a8490e120b4ab4230972f503e62aff24d0bfa5cdcef49bc8dcd082c69ade651f95e5cd0101780acdd389378fda
7
- data.tar.gz: eac7e0374494969be1ea08e8fb7344e163a2c122ff3d6b958d47851bc3815104329216c9107612930209ecf0551ff677a5d9f3744792d82746b410b32fe329d4
6
+ metadata.gz: 5251ca5fe770cfce8ad98f35ab31017b95d70d91e0088d640612c51f1506bb31e5484c26571cfc84503c686ab18f82a14b604698be5a0577072ef5dff6880cc7
7
+ data.tar.gz: f2c8f3e17ae79c3f79b9f736d3f31e317178cecacbc562900a592572596b283fdee1594267ccc3afb156426b7f7265a0d9ad9902bfc1a6a86e5f2db5622a9aa8
data/Rakefile CHANGED
@@ -15,19 +15,182 @@ task :check do
15
15
  sh "bundle exec steep check"
16
16
  end
17
17
 
18
+ desc "Compile wat"
19
+ task :wasm, [:name] do |t, args|
20
+ Dir.chdir "examples" do
21
+ sh "wat2wasm #{args.name}.wat"
22
+ end
23
+ end
24
+
18
25
  desc "Generate codes"
19
26
  task :generate do
20
27
  require_relative "scripts/gen_alu"
28
+ require_relative "scripts/gen_conv"
21
29
  libdir = File.expand_path("../lib", __FILE__)
22
30
 
23
31
  GenAlu.execute(libdir + "/wardite/alu_i32.generated.rb", prefix: "i32", defined_ops: [
32
+ :load,
33
+ :load8_s,
34
+ :load8_u,
35
+ :load16_s,
36
+ :load16_u,
37
+ :store,
38
+ :store8,
39
+ :store16,
40
+ :const,
41
+ :eqz,
42
+ :eq,
43
+ :ne,
24
44
  :lts,
45
+ :ltu,
46
+ :gts,
47
+ :gtu,
48
+ :les,
25
49
  :leu,
50
+ :ges,
51
+ :geu,
52
+ :clz,
53
+ :ctz,
54
+ :popcnt,
26
55
  :add,
27
56
  :sub,
57
+ :mul,
58
+ :div_s,
59
+ :div_u,
60
+ :rem_s,
61
+ :rem_u,
62
+ :and,
63
+ :or,
64
+ :xor,
65
+ :shl,
66
+ :shr_s,
67
+ :shr_u,
68
+ :rotl,
69
+ :rotr,
70
+ ])
71
+ GenAlu.execute(libdir + "/wardite/alu_i64.generated.rb", prefix: "i64", defined_ops: [
72
+ :load,
73
+ :load8_s,
74
+ :load8_u,
75
+ :load16_s,
76
+ :load16_u,
77
+ :load32_s,
78
+ :load32_u,
79
+ :store,
80
+ :store8,
81
+ :store16,
82
+ :store32,
28
83
  :const,
84
+ :eqz,
85
+ :eq,
86
+ :ne,
87
+ :lts,
88
+ :ltu,
89
+ :gts,
90
+ :gtu,
91
+ :les,
92
+ :leu,
93
+ :ges,
94
+ :geu,
95
+ :clz,
96
+ :ctz,
97
+ :popcnt,
98
+ :add,
99
+ :sub,
100
+ :mul,
101
+ :div_s,
102
+ :div_u,
103
+ :rem_s,
104
+ :rem_u,
105
+ :and,
106
+ :or,
107
+ :xor,
108
+ :shl,
109
+ :shr_s,
110
+ :shr_u,
111
+ :rotl,
112
+ :rotr,
113
+ ])
114
+ GenAlu.execute(libdir + "/wardite/alu_f32.generated.rb", prefix: "f32", defined_ops: [
115
+ :load,
29
116
  :store,
117
+ :const__f,
118
+ :eqz,
119
+ :eq,
120
+ :ne,
121
+ :lt,
122
+ :gt,
123
+ :le,
124
+ :ge,
125
+ :abs,
126
+ :neg,
127
+ :ceil,
128
+ :floor,
129
+ :trunc,
130
+ :nearest,
131
+ :sqrt,
132
+ :add,
133
+ :sub,
134
+ :mul,
135
+ :div,
136
+ :min,
137
+ :max,
138
+ :copysign,
30
139
  ])
140
+ GenAlu.execute(libdir + "/wardite/alu_f64.generated.rb", prefix: "f64", defined_ops: [
141
+ :load,
142
+ :store,
143
+ :const__f,
144
+ :eqz,
145
+ :eq,
146
+ :ne,
147
+ :lt,
148
+ :gt,
149
+ :le,
150
+ :ge,
151
+ :abs,
152
+ :neg,
153
+ :ceil,
154
+ :floor,
155
+ :trunc,
156
+ :nearest,
157
+ :sqrt,
158
+ :add,
159
+ :sub,
160
+ :mul,
161
+ :div,
162
+ :min,
163
+ :max,
164
+ :copysign,
165
+ ])
166
+
167
+ GenConv.execute(libdir + "/wardite/convert.generated.rb", defined_ops: {
168
+ i32: {
169
+ wrap: [:i64],
170
+ trunc_s: [:f32, :f64],
171
+ trunc_u: [:f32, :f64],
172
+ reinterpret: [:f32],
173
+ },
174
+ i64: {
175
+ extend_s: [:i32, :i64],
176
+ extend_u: [:i32, :i64],
177
+ trunc_s: [:f32, :f64],
178
+ trunc_u: [:f32, :f64],
179
+ reinterpret: [:f64],
180
+ },
181
+ f32: {
182
+ convert_s: [:i32, :i64],
183
+ convert_u: [:i32, :i64],
184
+ demote: [:f64],
185
+ reinterpret: [:i32],
186
+ },
187
+ f64: {
188
+ convert_s: [:i32, :i64],
189
+ convert_u: [:i32, :i64],
190
+ promote: [:f32],
191
+ reinterpret: [:i64],
192
+ },
193
+ })
31
194
  end
32
195
 
33
196
  task default: %i[test check]
data/Steepfile CHANGED
@@ -3,6 +3,7 @@ target :lib do
3
3
  signature "sig"
4
4
  check "lib"
5
5
 
6
+ library "pp"
6
7
  # configure_code_diagnostics(Steep::Diagnostic::Ruby.strict)
7
8
  end
8
9
 
@@ -0,0 +1,12 @@
1
+ (module
2
+ (func $test_const (result f32)
3
+ (i32.const 42)
4
+ (drop)
5
+ (i64.const 42)
6
+ (drop)
7
+ (f64.const 3.14)
8
+ (drop)
9
+ (f32.const 3.14)
10
+ )
11
+ (export "test_const" (func $test_const))
12
+ )
@@ -0,0 +1,13 @@
1
+ (module ;; from https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/Variables/Global_set
2
+ (global $var (mut i32) (i32.const 0))
3
+ (global $var2 (mut i32) (i32.const 40))
4
+ (func $main (result i32)
5
+ i32.const 10 ;; load a number onto the stack
6
+ global.set $var ;; set the $var
7
+
8
+ global.get $var ;; load $var onto the stack
9
+ global.get $var2
10
+ i32.add ;; 10 + 40
11
+ )
12
+ (export "test" (func $main))
13
+ )
@@ -0,0 +1,250 @@
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.f32_eval_insn(runtime, frame, insn)
11
+ case insn.code
12
+
13
+ when :f32_load
14
+ _align = insn.operand[0] # TODO: alignment support?
15
+ offset = insn.operand[1]
16
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
17
+
18
+ addr = runtime.stack.pop
19
+ if !addr.is_a?(I32)
20
+ raise EvalError, "maybe stack too short"
21
+ end
22
+
23
+ at = addr.value + offset
24
+ data_end = at + F32.new.memsize / 8
25
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
26
+ buf = memory.data[at...data_end]
27
+ if !buf
28
+ raise EvalError, "invalid memory range"
29
+ end
30
+ runtime.stack.push(F32.from_bytes(buf))
31
+
32
+
33
+ when :f32_store
34
+ _align = insn.operand[0] # TODO: alignment support?
35
+ offset = insn.operand[1]
36
+ raise EvalError, "[BUG] invalid type of operand" if !offset.is_a?(Integer)
37
+
38
+ value = runtime.stack.pop
39
+ addr = runtime.stack.pop
40
+ if !value.is_a?(F32) || !addr.is_a?(I32)
41
+ raise EvalError, "maybe stack too short"
42
+ end
43
+
44
+ at = addr.value + offset
45
+ data_end = at + value.packed.size
46
+ memory = runtime.instance.store.memories[0] || raise("[BUG] no memory")
47
+ memory.data[at...data_end] = value.packed
48
+
49
+
50
+ when :f32_const
51
+ const = insn.operand[0]
52
+ if !const.is_a?(Float)
53
+ raise EvalError, "invalid type of operand"
54
+ end
55
+ runtime.stack.push(F32(const))
56
+
57
+
58
+ when :f32_eqz
59
+ target = runtime.stack.pop
60
+ if !target.is_a?(F32)
61
+ raise EvalError, "maybe empty or invalid stack"
62
+ end
63
+ value = target.value.zero? ? 1 : 0
64
+ runtime.stack.push(I32(value))
65
+
66
+
67
+ when :f32_eq
68
+ right, left = runtime.stack.pop, runtime.stack.pop
69
+ if !right.is_a?(F32) || !left.is_a?(F32)
70
+ raise EvalError, "maybe empty or invalid stack"
71
+ end
72
+ value = (left.value == right.value) ? 1 : 0
73
+ runtime.stack.push(I32(value))
74
+
75
+
76
+ when :f32_ne
77
+ right, left = runtime.stack.pop, runtime.stack.pop
78
+ if !right.is_a?(F32) || !left.is_a?(F32)
79
+ raise EvalError, "maybe empty or invalid stack"
80
+ end
81
+ value = (left.value != right.value) ? 1 : 0
82
+ runtime.stack.push(I32(value))
83
+
84
+
85
+ when :f32_lt
86
+ right, left = runtime.stack.pop, runtime.stack.pop
87
+ if !right.is_a?(F32) || !left.is_a?(F32)
88
+ raise EvalError, "maybe empty or invalid stack"
89
+ end
90
+ value = (left.value < right.value) ? 1 : 0
91
+ runtime.stack.push(I32(value))
92
+
93
+
94
+ when :f32_gt
95
+ right, left = runtime.stack.pop, runtime.stack.pop
96
+ if !right.is_a?(F32) || !left.is_a?(F32)
97
+ raise EvalError, "maybe empty or invalid stack"
98
+ end
99
+ value = (left.value > right.value) ? 1 : 0
100
+ runtime.stack.push(I32(value))
101
+
102
+
103
+ when :f32_le
104
+ right, left = runtime.stack.pop, runtime.stack.pop
105
+ if !right.is_a?(F32) || !left.is_a?(F32)
106
+ raise EvalError, "maybe empty or invalid stack"
107
+ end
108
+ value = (left.value <= right.value) ? 1 : 0
109
+ runtime.stack.push(I32(value))
110
+
111
+
112
+ when :f32_ge
113
+ right, left = runtime.stack.pop, runtime.stack.pop
114
+ if !right.is_a?(F32) || !left.is_a?(F32)
115
+ raise EvalError, "maybe empty or invalid stack"
116
+ end
117
+ value = (left.value >= right.value) ? 1 : 0
118
+ runtime.stack.push(I32(value))
119
+
120
+
121
+ when :f32_abs
122
+ x = runtime.stack.pop
123
+ if !x.is_a?(F32)
124
+ raise EvalError, "maybe empty or invalid stack"
125
+ end
126
+ runtime.stack.push(F32(x.value.abs))
127
+
128
+
129
+ when :f32_neg
130
+ x = runtime.stack.pop
131
+ if !x.is_a?(F32)
132
+ raise EvalError, "maybe empty or invalid stack"
133
+ end
134
+ runtime.stack.push(F32(-(x.value)))
135
+
136
+
137
+ when :f32_ceil
138
+ x = runtime.stack.pop
139
+ if !x.is_a?(F32)
140
+ raise EvalError, "maybe empty or invalid stack"
141
+ end
142
+ runtime.stack.push(F32(x.value.ceil.to_f))
143
+
144
+
145
+ when :f32_floor
146
+ x = runtime.stack.pop
147
+ if !x.is_a?(F32)
148
+ raise EvalError, "maybe empty or invalid stack"
149
+ end
150
+ runtime.stack.push(F32(x.value.floor.to_f))
151
+
152
+
153
+ when :f32_trunc
154
+ x = runtime.stack.pop
155
+ if !x.is_a?(F32)
156
+ raise EvalError, "maybe empty or invalid stack"
157
+ end
158
+ runtime.stack.push(F32(x.value.to_i.to_f))
159
+
160
+
161
+ when :f32_nearest
162
+ x = runtime.stack.pop
163
+ if !x.is_a?(F32)
164
+ raise EvalError, "maybe empty or invalid stack"
165
+ end
166
+ runtime.stack.push(F32(x.value.round.to_f))
167
+
168
+
169
+ when :f32_sqrt
170
+ x = runtime.stack.pop
171
+ if !x.is_a?(F32)
172
+ raise EvalError, "maybe empty or invalid stack"
173
+ end
174
+ runtime.stack.push(F32(x.value ** 0.5))
175
+
176
+
177
+ when :f32_add
178
+ right, left = runtime.stack.pop, runtime.stack.pop
179
+ if !right.is_a?(F32) || !left.is_a?(F32)
180
+ raise EvalError, "maybe empty or invalid stack"
181
+ end
182
+ runtime.stack.push(F32(left.value + right.value))
183
+
184
+
185
+ when :f32_sub
186
+ right, left = runtime.stack.pop, runtime.stack.pop
187
+ if !right.is_a?(F32) || !left.is_a?(F32)
188
+ raise EvalError, "maybe empty or invalid stack"
189
+ end
190
+ runtime.stack.push(F32(left.value - right.value))
191
+
192
+
193
+ when :f32_mul
194
+ right, left = runtime.stack.pop, runtime.stack.pop
195
+ if !right.is_a?(F32) || !left.is_a?(F32)
196
+ raise EvalError, "maybe empty or invalid stack"
197
+ end
198
+ runtime.stack.push(F32(left.value * right.value))
199
+
200
+
201
+ when :f32_div
202
+ right, left = runtime.stack.pop, runtime.stack.pop
203
+ if !right.is_a?(F32) || !left.is_a?(F32)
204
+ raise EvalError, "maybe empty or invalid stack"
205
+ end
206
+ runtime.stack.push(F32(left.value / right.value))
207
+
208
+
209
+ when :f32_min
210
+ right, left = runtime.stack.pop, runtime.stack.pop
211
+ if !right.is_a?(F32) || !left.is_a?(F32)
212
+ raise EvalError, "maybe empty or invalid stack"
213
+ end
214
+ if right.value.nan? || left.value.nan?
215
+ runtime.stack.push(F32(Float::NAN))
216
+ return
217
+ end
218
+ runtime.stack.push(F32([left.value, right.value].min))
219
+
220
+
221
+ when :f32_max
222
+ right, left = runtime.stack.pop, runtime.stack.pop
223
+ if !right.is_a?(F32) || !left.is_a?(F32)
224
+ raise EvalError, "maybe empty or invalid stack"
225
+ end
226
+ if right.value.nan? || left.value.nan?
227
+ runtime.stack.push(F32(Float::NAN))
228
+ return
229
+ end
230
+ runtime.stack.push(F32([left.value, right.value].max))
231
+
232
+
233
+ when :f32_copysign
234
+ right, left = runtime.stack.pop, runtime.stack.pop
235
+ if !right.is_a?(F32) || !left.is_a?(F32)
236
+ raise EvalError, "maybe empty or invalid stack"
237
+ end
238
+ if left.sign == right.sign
239
+ runtime.stack.push(F32(left.value))
240
+ else
241
+ runtime.stack.push(F32(-left.value))
242
+ end
243
+
244
+
245
+ else
246
+ raise "Unknown opcode for namespace #{insn.namespace}: #{insn.code}"
247
+ end
248
+ end
249
+ end
250
+ end