wardite 0.2.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +6 -0
- data/examples/break.wat +13 -0
- data/examples/call_indirect.wat +15 -0
- data/examples/loop.wat +20 -0
- data/examples/memory_init.wat +18 -0
- data/examples/saturate.wat +8 -0
- data/examples/saturate_u.wat +9 -0
- data/examples/start.wat +12 -0
- data/lib/wardite/const.rb +13 -12
- data/lib/wardite/convert.generated.rb +104 -0
- data/lib/wardite/instruction.rb +67 -8
- data/lib/wardite/load.rb +216 -28
- data/lib/wardite/value.rb +247 -70
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite/wasi.rb +2 -2
- data/lib/wardite.rb +471 -17
- data/scripts/gen_conv.rb +12 -2
- data/sig/generated/wardite/const.rbs +2 -0
- data/sig/generated/wardite/instruction.rbs +15 -3
- data/sig/generated/wardite/load.rbs +63 -7
- data/sig/generated/wardite/value.rbs +142 -82
- data/sig/generated/wardite/wasi.rbs +4 -4
- data/sig/generated/wardite.rbs +103 -17
- data/sig/wardite.rbs +1 -3
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d2b7f37620b7290c9a4c1fc558024d87cb7ad73bf217c7f7abbda3e6dfda266
|
4
|
+
data.tar.gz: c239d24ee56a9dd80084abc11dcffad7a40edbc2c4644146c3cf91fa5b393ddd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a9369b5cb946190e8dd0f0fc5c17d383e9f5f168098332b78a4ed821398f0a6d7b631558ba6a8a32a14d9ebcce88dd23e8f05d32b73eb7d9e7aafa14a46b0f4
|
7
|
+
data.tar.gz: 62f7f961e035a39203616793aa257d238a62760c70f6c9184070d3b79cc0615b829fbe5c4b89608838efe3db6b1a9e26332a125530992fcb41dcd64df8df3304
|
data/Rakefile
CHANGED
@@ -170,6 +170,9 @@ task :generate do
|
|
170
170
|
trunc_s: [:f32, :f64],
|
171
171
|
trunc_u: [:f32, :f64],
|
172
172
|
reinterpret: [:f32],
|
173
|
+
extendN_s: [:i8, :i16],
|
174
|
+
trunc_sat_s: [:f32, :f64],
|
175
|
+
trunc_sat_u: [:f32, :f64],
|
173
176
|
},
|
174
177
|
i64: {
|
175
178
|
extend_s: [:i32, :i64],
|
@@ -177,6 +180,9 @@ task :generate do
|
|
177
180
|
trunc_s: [:f32, :f64],
|
178
181
|
trunc_u: [:f32, :f64],
|
179
182
|
reinterpret: [:f64],
|
183
|
+
extendN_s: [:i8, :i16, :i32],
|
184
|
+
trunc_sat_s: [:f32, :f64],
|
185
|
+
trunc_sat_u: [:f32, :f64],
|
180
186
|
},
|
181
187
|
f32: {
|
182
188
|
convert_s: [:i32, :i64],
|
data/examples/break.wat
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
;; https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/Control_flow/block
|
2
|
+
(module
|
3
|
+
(func (export "ret_if_100") (param $num i32) (result i32)
|
4
|
+
(block $my_block
|
5
|
+
local.get $num
|
6
|
+
i32.const 100
|
7
|
+
i32.eq
|
8
|
+
(if
|
9
|
+
(then
|
10
|
+
br $my_block))
|
11
|
+
i32.const -1
|
12
|
+
local.set $num)
|
13
|
+
local.get $num))
|
@@ -0,0 +1,15 @@
|
|
1
|
+
(module
|
2
|
+
;; ref https://ukyo.github.io/wasm-usui-book/webroot/get-started-webassembly.html
|
3
|
+
;; and https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format
|
4
|
+
(type $return_i32 (func (result i32)))
|
5
|
+
(table 3 funcref)
|
6
|
+
(elem (i32.const 0) $f1 $f2 $f3)
|
7
|
+
|
8
|
+
(func $f1 (result i32) i32.const 111)
|
9
|
+
(func $f2 (result i32) i32.const 222)
|
10
|
+
(func $f3 (result i32) i32.const 333)
|
11
|
+
|
12
|
+
(func (export "call_indirect") (param $i i32) (result i32)
|
13
|
+
local.get $i
|
14
|
+
call_indirect (type $return_i32))
|
15
|
+
)
|
data/examples/loop.wat
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
(module ;; https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/Control_flow/br
|
2
|
+
(global $i (mut i32) (i32.const 0))
|
3
|
+
|
4
|
+
(func $count (result i32)
|
5
|
+
(loop $my_loop (result i32)
|
6
|
+
global.get $i
|
7
|
+
i32.const 1
|
8
|
+
i32.add
|
9
|
+
global.set $i
|
10
|
+
|
11
|
+
global.get $i
|
12
|
+
global.get $i
|
13
|
+
i32.const 10
|
14
|
+
i32.lt_s
|
15
|
+
br_if $my_loop
|
16
|
+
)
|
17
|
+
)
|
18
|
+
|
19
|
+
(export "count" (func $count))
|
20
|
+
)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
(module ;;
|
2
|
+
(memory 1)
|
3
|
+
(data (i32.const 0) "hello") ;; data segment 0, is active so always copied
|
4
|
+
(data "goodbye") ;; data segment 1, is passive
|
5
|
+
|
6
|
+
(func $start (param $test i32) (result i32)
|
7
|
+
(if (local.get $test)
|
8
|
+
(then (memory.init 1
|
9
|
+
(i32.const 16)
|
10
|
+
(i32.const 0)
|
11
|
+
(i32.const 7))
|
12
|
+
(return (i32.const 1))
|
13
|
+
)
|
14
|
+
)
|
15
|
+
(return (i32.const 0))
|
16
|
+
)
|
17
|
+
(export "test" (func $start))
|
18
|
+
)
|
data/examples/start.wat
ADDED
data/lib/wardite/const.rb
CHANGED
@@ -3,18 +3,19 @@ module Wardite
|
|
3
3
|
module Const
|
4
4
|
# Section Code
|
5
5
|
# @see https://www.w3.org/TR/wasm-core-1/#sections%E2%91%A0
|
6
|
-
SectionCustom
|
7
|
-
SectionType
|
8
|
-
SectionImport
|
9
|
-
SectionFunction
|
10
|
-
SectionTable
|
11
|
-
SectionMemory
|
12
|
-
SectionGlobal
|
13
|
-
SectionExport
|
14
|
-
SectionStart
|
15
|
-
SectionElement
|
16
|
-
SectionCode
|
17
|
-
SectionData
|
6
|
+
SectionCustom = 0x0 #: Integer
|
7
|
+
SectionType = 0x1 #: Integer
|
8
|
+
SectionImport = 0x2 #: Integer
|
9
|
+
SectionFunction = 0x3 #: Integer
|
10
|
+
SectionTable = 0x4 #: Integer
|
11
|
+
SectionMemory = 0x5 #: Integer
|
12
|
+
SectionGlobal = 0x6 #: Integer
|
13
|
+
SectionExport = 0x7 #: Integer
|
14
|
+
SectionStart = 0x8 #: Integer
|
15
|
+
SectionElement = 0x9 #: Integer
|
16
|
+
SectionCode = 0xa #: Integer
|
17
|
+
SectionData = 0xb #: Integer
|
18
|
+
SectionDataCount = 0xc #: Integer
|
18
19
|
end
|
19
20
|
include Const
|
20
21
|
end
|
@@ -58,6 +58,54 @@ module Wardite
|
|
58
58
|
runtime.stack.push(to)
|
59
59
|
|
60
60
|
|
61
|
+
when :i32_extend_8_s
|
62
|
+
from = runtime.stack.pop
|
63
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
64
|
+
to = from.extendN_s(to: :i32, from: :i8)
|
65
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I32)
|
66
|
+
runtime.stack.push(to)
|
67
|
+
|
68
|
+
|
69
|
+
when :i32_extend_16_s
|
70
|
+
from = runtime.stack.pop
|
71
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
72
|
+
to = from.extendN_s(to: :i32, from: :i16)
|
73
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I32)
|
74
|
+
runtime.stack.push(to)
|
75
|
+
|
76
|
+
|
77
|
+
when :i32_trunc_sat_f32_s
|
78
|
+
from = runtime.stack.pop
|
79
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
|
80
|
+
to = from.trunc_sat_s(to: :i32)
|
81
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I32)
|
82
|
+
runtime.stack.push(to)
|
83
|
+
|
84
|
+
|
85
|
+
when :i32_trunc_sat_f64_s
|
86
|
+
from = runtime.stack.pop
|
87
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
|
88
|
+
to = from.trunc_sat_s(to: :i32)
|
89
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I32)
|
90
|
+
runtime.stack.push(to)
|
91
|
+
|
92
|
+
|
93
|
+
when :i32_trunc_sat_f32_u
|
94
|
+
from = runtime.stack.pop
|
95
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
|
96
|
+
to = from.trunc_sat_u(to: :i32)
|
97
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I32)
|
98
|
+
runtime.stack.push(to)
|
99
|
+
|
100
|
+
|
101
|
+
when :i32_trunc_sat_f64_u
|
102
|
+
from = runtime.stack.pop
|
103
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
|
104
|
+
to = from.trunc_sat_u(to: :i32)
|
105
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I32)
|
106
|
+
runtime.stack.push(to)
|
107
|
+
|
108
|
+
|
61
109
|
when :i64_extend_i32_s
|
62
110
|
from = runtime.stack.pop
|
63
111
|
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
@@ -130,6 +178,62 @@ module Wardite
|
|
130
178
|
runtime.stack.push(to)
|
131
179
|
|
132
180
|
|
181
|
+
when :i64_extend_8_s
|
182
|
+
from = runtime.stack.pop
|
183
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
184
|
+
to = from.extendN_s(to: :i64, from: :i8)
|
185
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
186
|
+
runtime.stack.push(to)
|
187
|
+
|
188
|
+
|
189
|
+
when :i64_extend_16_s
|
190
|
+
from = runtime.stack.pop
|
191
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
192
|
+
to = from.extendN_s(to: :i64, from: :i16)
|
193
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
194
|
+
runtime.stack.push(to)
|
195
|
+
|
196
|
+
|
197
|
+
when :i64_extend_32_s
|
198
|
+
from = runtime.stack.pop
|
199
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
200
|
+
to = from.extendN_s(to: :i64, from: :i32)
|
201
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
202
|
+
runtime.stack.push(to)
|
203
|
+
|
204
|
+
|
205
|
+
when :i64_trunc_sat_f32_s
|
206
|
+
from = runtime.stack.pop
|
207
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
|
208
|
+
to = from.trunc_sat_s(to: :i64)
|
209
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
210
|
+
runtime.stack.push(to)
|
211
|
+
|
212
|
+
|
213
|
+
when :i64_trunc_sat_f64_s
|
214
|
+
from = runtime.stack.pop
|
215
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
|
216
|
+
to = from.trunc_sat_s(to: :i64)
|
217
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
218
|
+
runtime.stack.push(to)
|
219
|
+
|
220
|
+
|
221
|
+
when :i64_trunc_sat_f32_u
|
222
|
+
from = runtime.stack.pop
|
223
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F32)
|
224
|
+
to = from.trunc_sat_u(to: :i64)
|
225
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
226
|
+
runtime.stack.push(to)
|
227
|
+
|
228
|
+
|
229
|
+
when :i64_trunc_sat_f64_u
|
230
|
+
from = runtime.stack.pop
|
231
|
+
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(F64)
|
232
|
+
to = from.trunc_sat_u(to: :i64)
|
233
|
+
raise EvalError, "failed to convert type" if !to.is_a?(I64)
|
234
|
+
runtime.stack.push(to)
|
235
|
+
|
236
|
+
|
133
237
|
when :f32_convert_i32_s
|
134
238
|
from = runtime.stack.pop
|
135
239
|
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(I32)
|
data/lib/wardite/instruction.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# rbs_inline: enabled
|
2
2
|
|
3
3
|
module Wardite
|
4
|
+
# @rbs!
|
5
|
+
# type operandItem = Integer | Array[Integer] | Float | Block
|
6
|
+
|
4
7
|
class Op
|
5
8
|
# @see https://pengowray.github.io/wasm-ops/
|
6
9
|
SYMS = %i[
|
@@ -28,15 +31,27 @@ module Wardite
|
|
28
31
|
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
32
|
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
33
|
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
|
34
|
+
i32_extend8_s i32_extend16_s i64_extend8_s i64_extend16_s i64_extend32_s
|
35
|
+
__unsuported_from_here_on__
|
36
|
+
] #: Array[Symbol]
|
37
|
+
|
38
|
+
FC_SYMS = %i[
|
39
|
+
i32_trunc_sat_f32_s i32_trunc_sat_f32_u i32_trunc_sat_f64_s i32_trunc_sat_f64_u
|
40
|
+
i64_trunc_sat_f32_s i64_trunc_sat_f32_u i64_trunc_sat_f64_s i64_trunc_sat_f64_u
|
41
|
+
memory_init data_drop memory_copy memory_fill
|
42
|
+
table_init elem_drop table_copy table_grow
|
43
|
+
table_size table_fill
|
31
44
|
__unsuported_from_here_on__
|
32
45
|
] #: Array[Symbol]
|
33
46
|
|
34
47
|
# @rbs @@table: Hash[Integer, Symbol] | nil
|
35
|
-
@@table = nil
|
48
|
+
@@table = nil
|
49
|
+
# @rbs @@table: Hash[Integer, Symbol] | nil
|
50
|
+
@@fc_table = nil
|
36
51
|
|
37
52
|
# @rbs return: Hash[Integer, Symbol]
|
38
53
|
def self.table
|
39
|
-
@@table if @@table != nil
|
54
|
+
return @@table if @@table != nil
|
40
55
|
@@table = {}.tap do |ha|
|
41
56
|
SYMS.each_with_index do |sym, i|
|
42
57
|
ha[i] = sym
|
@@ -45,16 +60,27 @@ module Wardite
|
|
45
60
|
@@table
|
46
61
|
end
|
47
62
|
|
63
|
+
# @rbs return: Hash[Integer, Symbol]
|
64
|
+
def self.fc_table
|
65
|
+
return @@fc_table if @@fc_table != nil
|
66
|
+
@@fc_table = {}.tap do |ha|
|
67
|
+
FC_SYMS.each_with_index do |sym, i|
|
68
|
+
ha[i] = sym
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@@fc_table
|
72
|
+
end
|
73
|
+
|
48
74
|
attr_accessor :namespace #: Symbol
|
49
75
|
|
50
76
|
attr_accessor :code #: Symbol
|
51
77
|
|
52
78
|
# TODO: add types of potential operands
|
53
|
-
attr_accessor :operand #: Array[
|
79
|
+
attr_accessor :operand #: Array[operandItem]
|
54
80
|
|
55
81
|
# @rbs namespace: Symbol
|
56
82
|
# @rbs code: Symbol
|
57
|
-
# @rbs operand: Array[
|
83
|
+
# @rbs operand: Array[operandItem]
|
58
84
|
def initialize(namespace, code, operand)
|
59
85
|
@namespace = namespace
|
60
86
|
@code = code
|
@@ -64,6 +90,10 @@ module Wardite
|
|
64
90
|
# @rbs chr: String
|
65
91
|
# @rbs return: [Symbol, Symbol]
|
66
92
|
def self.to_sym(chr)
|
93
|
+
if chr.ord == 0xfc
|
94
|
+
return [:fc, :fc]
|
95
|
+
end
|
96
|
+
|
67
97
|
code = table[chr.ord]
|
68
98
|
if ! code
|
69
99
|
raise "found unknown code 0x#{chr.ord.to_s(16)}"
|
@@ -82,6 +112,28 @@ module Wardite
|
|
82
112
|
end
|
83
113
|
end
|
84
114
|
|
115
|
+
# @rbs lower: Integer
|
116
|
+
# @rbs return: [Symbol, Symbol]
|
117
|
+
def self.resolve_fc_sym(lower)
|
118
|
+
if lower == 0xfc
|
119
|
+
return [:fc, :fc]
|
120
|
+
end
|
121
|
+
|
122
|
+
code = fc_table[lower]
|
123
|
+
if ! code
|
124
|
+
raise "found unknown code 0xfc 0x#{lower.to_s(16)}"
|
125
|
+
end
|
126
|
+
|
127
|
+
prefix = code.to_s.split("_")[0]
|
128
|
+
case prefix
|
129
|
+
when "i32", "i64", "f32", "f64"
|
130
|
+
# All FC operations for numeric are "convert"
|
131
|
+
[:convert, code]
|
132
|
+
else
|
133
|
+
[:default, code]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
85
137
|
# @rbs code: Symbol
|
86
138
|
# @rbs return: Array[Symbol]
|
87
139
|
def self.operand_of(code)
|
@@ -90,8 +142,12 @@ module Wardite
|
|
90
142
|
[:u32, :u32]
|
91
143
|
when :local_get, :local_set, :local_tee, :global_get, :global_set, :call, :br, :br_if
|
92
144
|
[:u32]
|
145
|
+
when :memory_init, :memory_copy
|
146
|
+
[:u32, :u32]
|
147
|
+
when :memory_size, :memory_grow, :memory_fill
|
148
|
+
[:u32]
|
93
149
|
when :call_indirect
|
94
|
-
[:u32, :
|
150
|
+
[:u32, :u32]
|
95
151
|
when :br_table
|
96
152
|
[:u32_vec, :u32]
|
97
153
|
when :i32_const
|
@@ -102,9 +158,7 @@ module Wardite
|
|
102
158
|
[:f32]
|
103
159
|
when :f64_const
|
104
160
|
[:f64]
|
105
|
-
when :if
|
106
|
-
[:u8_if_block]
|
107
|
-
when :block, :loop
|
161
|
+
when :if, :block, :loop
|
108
162
|
[:u8_block]
|
109
163
|
else
|
110
164
|
[]
|
@@ -112,10 +166,15 @@ module Wardite
|
|
112
166
|
end
|
113
167
|
|
114
168
|
# @see https://www.w3.org/TR/wasm-core-1/#value-types%E2%91%A2
|
169
|
+
# We use this for reftype conversion. https://webassembly.github.io/spec/core/binary/types.html#binary-reftype
|
115
170
|
# @rbs code: Integer
|
116
171
|
# @rbs return: Symbol
|
117
172
|
def self.i2type(code)
|
118
173
|
case code
|
174
|
+
when 0x6f
|
175
|
+
:externref
|
176
|
+
when 0x70
|
177
|
+
:funcref
|
119
178
|
when 0x7f
|
120
179
|
:i32
|
121
180
|
when 0x7e
|