wardite 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|