wardite 0.3.0 → 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/memory_init.wat +18 -0
- data/examples/saturate.wat +8 -0
- data/examples/saturate_u.wat +9 -0
- data/lib/wardite/const.rb +13 -12
- data/lib/wardite/convert.generated.rb +104 -0
- data/lib/wardite/instruction.rb +56 -3
- data/lib/wardite/load.rb +86 -19
- data/lib/wardite/value.rb +202 -28
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite.rb +85 -3
- data/scripts/gen_conv.rb +12 -2
- data/sig/generated/wardite/const.rbs +2 -0
- data/sig/generated/wardite/instruction.rbs +9 -0
- data/sig/generated/wardite/load.rbs +19 -1
- data/sig/generated/wardite/value.rbs +64 -6
- data/sig/generated/wardite.rbs +6 -0
- metadata +4 -1
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],
|
@@ -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/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
@@ -31,15 +31,27 @@ module Wardite
|
|
31
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
|
32
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
|
33
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
|
34
35
|
__unsuported_from_here_on__
|
35
36
|
] #: Array[Symbol]
|
36
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
|
44
|
+
__unsuported_from_here_on__
|
45
|
+
] #: Array[Symbol]
|
46
|
+
|
47
|
+
# @rbs @@table: Hash[Integer, Symbol] | nil
|
48
|
+
@@table = nil
|
37
49
|
# @rbs @@table: Hash[Integer, Symbol] | nil
|
38
|
-
@@
|
50
|
+
@@fc_table = nil
|
39
51
|
|
40
52
|
# @rbs return: Hash[Integer, Symbol]
|
41
53
|
def self.table
|
42
|
-
@@table if @@table != nil
|
54
|
+
return @@table if @@table != nil
|
43
55
|
@@table = {}.tap do |ha|
|
44
56
|
SYMS.each_with_index do |sym, i|
|
45
57
|
ha[i] = sym
|
@@ -48,6 +60,17 @@ module Wardite
|
|
48
60
|
@@table
|
49
61
|
end
|
50
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
|
+
|
51
74
|
attr_accessor :namespace #: Symbol
|
52
75
|
|
53
76
|
attr_accessor :code #: Symbol
|
@@ -67,6 +90,10 @@ module Wardite
|
|
67
90
|
# @rbs chr: String
|
68
91
|
# @rbs return: [Symbol, Symbol]
|
69
92
|
def self.to_sym(chr)
|
93
|
+
if chr.ord == 0xfc
|
94
|
+
return [:fc, :fc]
|
95
|
+
end
|
96
|
+
|
70
97
|
code = table[chr.ord]
|
71
98
|
if ! code
|
72
99
|
raise "found unknown code 0x#{chr.ord.to_s(16)}"
|
@@ -85,6 +112,28 @@ module Wardite
|
|
85
112
|
end
|
86
113
|
end
|
87
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
|
+
|
88
137
|
# @rbs code: Symbol
|
89
138
|
# @rbs return: Array[Symbol]
|
90
139
|
def self.operand_of(code)
|
@@ -93,8 +142,12 @@ module Wardite
|
|
93
142
|
[:u32, :u32]
|
94
143
|
when :local_get, :local_set, :local_tee, :global_get, :global_set, :call, :br, :br_if
|
95
144
|
[:u32]
|
145
|
+
when :memory_init, :memory_copy
|
146
|
+
[:u32, :u32]
|
147
|
+
when :memory_size, :memory_grow, :memory_fill
|
148
|
+
[:u32]
|
96
149
|
when :call_indirect
|
97
|
-
[:u32, :
|
150
|
+
[:u32, :u32]
|
98
151
|
when :br_table
|
99
152
|
[:u32_vec, :u32]
|
100
153
|
when :i32_const
|
data/lib/wardite/load.rb
CHANGED
@@ -148,7 +148,9 @@ module Wardite
|
|
148
148
|
|
149
149
|
class DataSection < Section
|
150
150
|
class Segment
|
151
|
-
attr_accessor :
|
151
|
+
attr_accessor :mode #: :active|:passive
|
152
|
+
|
153
|
+
attr_accessor :mem_index #: Integer
|
152
154
|
|
153
155
|
attr_accessor :offset #: Integer
|
154
156
|
|
@@ -172,6 +174,19 @@ module Wardite
|
|
172
174
|
end
|
173
175
|
end
|
174
176
|
|
177
|
+
class DataCountSection < Section
|
178
|
+
attr_accessor :count #: Integer
|
179
|
+
|
180
|
+
# @rbs count: Integer
|
181
|
+
# @rbs return: void
|
182
|
+
def initialize(count)
|
183
|
+
self.name = "Data"
|
184
|
+
self.code = 0xc
|
185
|
+
|
186
|
+
@count = count
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
175
190
|
class ExportSection < Section
|
176
191
|
class ExportDesc
|
177
192
|
attr_accessor :name #: String
|
@@ -310,6 +325,8 @@ module Wardite
|
|
310
325
|
code_section
|
311
326
|
when Wardite::SectionData
|
312
327
|
data_section
|
328
|
+
when Wardite::Const::SectionDataCount
|
329
|
+
data_count_section
|
313
330
|
when Wardite::SectionCustom
|
314
331
|
unimplemented_skip_section(code)
|
315
332
|
else
|
@@ -590,7 +607,7 @@ module Wardite
|
|
590
607
|
def self.code_body(buf)
|
591
608
|
dest = []
|
592
609
|
while c = buf.read(1)
|
593
|
-
namespace, code =
|
610
|
+
namespace, code = resolve_code(c, buf)
|
594
611
|
operand_types = Op.operand_of(code)
|
595
612
|
operand = [] #: Array[operandItem]
|
596
613
|
operand_types.each do |typ|
|
@@ -652,6 +669,18 @@ module Wardite
|
|
652
669
|
dest
|
653
670
|
end
|
654
671
|
|
672
|
+
# @rbs c: String
|
673
|
+
# @rbs buf: StringIO
|
674
|
+
# @rbs return: [Symbol, Symbol]
|
675
|
+
def self.resolve_code(c, buf)
|
676
|
+
namespace, code = Op.to_sym(c)
|
677
|
+
if namespace == :fc
|
678
|
+
lower = fetch_uleb128(buf)
|
679
|
+
return Op.resolve_fc_sym(lower) #: [Symbol, Symbol]
|
680
|
+
end
|
681
|
+
return [namespace, code] #: [Symbol, Symbol]
|
682
|
+
end
|
683
|
+
|
655
684
|
# @rbs return: DataSection
|
656
685
|
def self.data_section
|
657
686
|
dest = DataSection.new
|
@@ -661,27 +690,54 @@ module Wardite
|
|
661
690
|
|
662
691
|
len = fetch_uleb128(sbuf)
|
663
692
|
len.times do |i|
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
693
|
+
data_type = fetch_uleb128(sbuf)
|
694
|
+
case data_type
|
695
|
+
when 0x0
|
696
|
+
# active
|
697
|
+
code = fetch_insn_while_end(sbuf)
|
698
|
+
ops = code_body(StringIO.new(code))
|
699
|
+
offset = decode_expr(ops)
|
700
|
+
len = fetch_uleb128(sbuf)
|
701
|
+
data = sbuf.read len
|
702
|
+
if !data
|
703
|
+
raise LoadError, "buffer too short"
|
704
|
+
end
|
705
|
+
segment = DataSection::Segment.new do |seg|
|
706
|
+
seg.mode = :active
|
707
|
+
seg.mem_index = 0 # memory index
|
708
|
+
seg.offset = offset
|
709
|
+
seg.data = data
|
710
|
+
end
|
711
|
+
dest.segments << segment
|
712
|
+
when 0x1
|
713
|
+
# passive
|
714
|
+
dsize = fetch_uleb128(sbuf)
|
715
|
+
data = sbuf.read dsize
|
716
|
+
if !data
|
717
|
+
raise LoadError, "data too short"
|
718
|
+
end
|
719
|
+
segment = DataSection::Segment.new do |seg|
|
720
|
+
seg.mode = :passive
|
721
|
+
seg.mem_index = 0 # unused
|
722
|
+
seg.offset = 0 # unused
|
723
|
+
seg.data = data
|
724
|
+
end
|
725
|
+
dest.segments << segment
|
679
726
|
end
|
680
|
-
dest.segments << segment
|
681
727
|
end
|
682
728
|
dest
|
683
729
|
end
|
684
730
|
|
731
|
+
# @rbs return: DataCountSection
|
732
|
+
def self.data_count_section
|
733
|
+
size = fetch_uleb128(@buf)
|
734
|
+
sbuf = StringIO.new(@buf.read(size) || raise("buffer too short"))
|
735
|
+
count = fetch_uleb128(sbuf)
|
736
|
+
dest = DataCountSection.new(count)
|
737
|
+
dest.size = size
|
738
|
+
dest
|
739
|
+
end
|
740
|
+
|
685
741
|
# @rbs sbuf: StringIO
|
686
742
|
# @rbs return: String
|
687
743
|
def self.fetch_insn_while_end(sbuf)
|
@@ -740,7 +796,18 @@ module Wardite
|
|
740
796
|
raise "Invalid definition of operand"
|
741
797
|
end
|
742
798
|
return I64(arg)
|
743
|
-
|
799
|
+
when :f32_const
|
800
|
+
arg = op.operand[0]
|
801
|
+
if !arg.is_a?(Float)
|
802
|
+
raise "Invalid definition of operand"
|
803
|
+
end
|
804
|
+
return F32(arg)
|
805
|
+
when :f64_const
|
806
|
+
arg = op.operand[0]
|
807
|
+
if !arg.is_a?(Float)
|
808
|
+
raise "Invalid definition of operand"
|
809
|
+
end
|
810
|
+
return F64(arg)
|
744
811
|
else
|
745
812
|
raise "Unimplemented offset op: #{op.code.inspect}"
|
746
813
|
end
|
data/lib/wardite/value.rb
CHANGED
@@ -56,7 +56,7 @@ module Wardite
|
|
56
56
|
class I32
|
57
57
|
include ValueHelper
|
58
58
|
|
59
|
-
I32_MAX = (1<<32) - 1
|
59
|
+
I32_MAX = (1<<32) - 1 #: Integer
|
60
60
|
# value should be stored as unsigned Integer, even in I32/I64
|
61
61
|
# when we want to access signed value, it'd be done via #value_s
|
62
62
|
attr_accessor :value #: Integer
|
@@ -190,6 +190,49 @@ module Wardite
|
|
190
190
|
F32(v)
|
191
191
|
end
|
192
192
|
|
193
|
+
# @rbs from: Symbol
|
194
|
+
# @rbs to: Symbol
|
195
|
+
# @rbs return: wasmValue
|
196
|
+
def extendN_s(from:, to:)
|
197
|
+
src_value = case from
|
198
|
+
when :i8
|
199
|
+
base = value & 0xff
|
200
|
+
(base >> 8).zero? ?
|
201
|
+
base :
|
202
|
+
((-base) ^ 0xff) + 1
|
203
|
+
when :i16
|
204
|
+
base = value & 0xffff
|
205
|
+
(base >> 15).zero? ?
|
206
|
+
base :
|
207
|
+
((-base) ^ 0xffff) + 1
|
208
|
+
when :i32
|
209
|
+
value_s
|
210
|
+
else
|
211
|
+
raise EvalError, "unsupported value size"
|
212
|
+
end
|
213
|
+
|
214
|
+
case to
|
215
|
+
when :i32
|
216
|
+
I32(src_value)
|
217
|
+
when :i64
|
218
|
+
I64(src_value)
|
219
|
+
else
|
220
|
+
raise EvalError, "unsupported value size"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# @rbs to: Symbol
|
225
|
+
# @rbs return: wasmValue
|
226
|
+
def trunc_sat_u(to:)
|
227
|
+
raise EvalError, "unsupported operation"
|
228
|
+
end
|
229
|
+
|
230
|
+
# @rbs to: Symbol
|
231
|
+
# @rbs return: wasmValue
|
232
|
+
def trunc_sat_s(to:)
|
233
|
+
raise EvalError, "unsupported operation"
|
234
|
+
end
|
235
|
+
|
193
236
|
# I32#inspect shows signed value for convinience
|
194
237
|
def inspect
|
195
238
|
"I32(#{value_s})"
|
@@ -199,7 +242,7 @@ module Wardite
|
|
199
242
|
class I64
|
200
243
|
include ValueHelper
|
201
244
|
|
202
|
-
I64_MAX = (1<<64) - 1
|
245
|
+
I64_MAX = (1<<64) - 1 #: Integer
|
203
246
|
|
204
247
|
attr_accessor :value #: Integer
|
205
248
|
|
@@ -334,6 +377,25 @@ module Wardite
|
|
334
377
|
F32(v)
|
335
378
|
end
|
336
379
|
|
380
|
+
# @rbs from: Symbol
|
381
|
+
# @rbs to: Symbol
|
382
|
+
# @rbs return: wasmValue
|
383
|
+
def extendN_s(from:, to:)
|
384
|
+
raise EvalError, "unsupported operation"
|
385
|
+
end
|
386
|
+
|
387
|
+
# @rbs to: Symbol
|
388
|
+
# @rbs return: wasmValue
|
389
|
+
def trunc_sat_u(to:)
|
390
|
+
raise EvalError, "unsupported operation"
|
391
|
+
end
|
392
|
+
|
393
|
+
# @rbs to: Symbol
|
394
|
+
# @rbs return: wasmValue
|
395
|
+
def trunc_sat_s(to:)
|
396
|
+
raise EvalError, "unsupported operation"
|
397
|
+
end
|
398
|
+
|
337
399
|
# I64#inspect shows signed value
|
338
400
|
def inspect
|
339
401
|
"I64(#{@value})"
|
@@ -395,28 +457,52 @@ module Wardite
|
|
395
457
|
|
396
458
|
# @todo need more testcase...
|
397
459
|
# @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-s-mathrm-trunc-mathsf-s-m-n-z
|
460
|
+
# @see copy this impl to F64 when changed
|
398
461
|
# @rbs to: Symbol
|
462
|
+
# @rbs saturating: bool
|
399
463
|
# @rbs return: wasmValue
|
400
|
-
def trunc_s(to:)
|
464
|
+
def trunc_s(to:, saturating: false)
|
401
465
|
v = value.to_i
|
402
466
|
case to
|
403
467
|
when :i32
|
404
468
|
if v >= 0
|
405
|
-
|
469
|
+
i32_signed_max = I32::I32_MAX >> 1
|
470
|
+
if saturating
|
471
|
+
v = i32_signed_max if v > i32_signed_max
|
472
|
+
else
|
473
|
+
v = v & i32_signed_max
|
474
|
+
end
|
475
|
+
I32(v & i32_signed_max)
|
406
476
|
else
|
407
|
-
|
408
|
-
if
|
409
|
-
|
477
|
+
i32_signed_min = -(I32::I32_MAX >> 1) - 1
|
478
|
+
if saturating
|
479
|
+
v = i32_signed_min if v < i32_signed_min
|
480
|
+
else
|
481
|
+
v = v & I32::I32_MAX
|
482
|
+
if (v >> 31).zero?
|
483
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
484
|
+
end
|
410
485
|
end
|
411
486
|
I32(v)
|
412
487
|
end
|
413
488
|
when :i64
|
414
489
|
if v >= 0
|
415
|
-
|
490
|
+
i64_signed_max = I64::I64_MAX >> 1
|
491
|
+
if saturating
|
492
|
+
v = i64_signed_max if v > i64_signed_max
|
493
|
+
else
|
494
|
+
v = v & i64_signed_max
|
495
|
+
end
|
496
|
+
I64(v & i64_signed_max)
|
416
497
|
else
|
417
|
-
|
418
|
-
if
|
419
|
-
|
498
|
+
i64_signed_min = -(I64::I64_MAX >> 1) - 1
|
499
|
+
if saturating
|
500
|
+
v = i64_signed_min if v < i64_signed_min
|
501
|
+
else
|
502
|
+
v = v & I64::I64_MAX
|
503
|
+
if (v >> 63).zero?
|
504
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
505
|
+
end
|
420
506
|
end
|
421
507
|
I64(v)
|
422
508
|
end
|
@@ -426,19 +512,33 @@ module Wardite
|
|
426
512
|
end
|
427
513
|
|
428
514
|
# @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-u-mathrm-trunc-mathsf-u-m-n-z
|
515
|
+
# @see copy this impl to F64 when changed
|
429
516
|
# @rbs to: Symbol
|
517
|
+
# @rbs sturating: bool
|
430
518
|
# @rbs return: wasmValue
|
431
|
-
def trunc_u(to:)
|
519
|
+
def trunc_u(to:, saturating: false)
|
432
520
|
v = value.to_i
|
433
521
|
if v < 0
|
434
|
-
|
522
|
+
if saturating
|
523
|
+
v = 0
|
524
|
+
else
|
525
|
+
raise EvalError, "[undefined behavior] unexpected negative value"
|
526
|
+
end
|
435
527
|
end
|
436
528
|
case to
|
437
529
|
when :i32
|
438
|
-
|
530
|
+
if saturating
|
531
|
+
v = I32::I32_MAX if v > I32::I32_MAX
|
532
|
+
else
|
533
|
+
v = v & I32::I32_MAX
|
534
|
+
end
|
439
535
|
I32(v)
|
440
536
|
when :i64
|
441
|
-
|
537
|
+
if saturating
|
538
|
+
v = I64::I64_MAX if v > I64::I64_MAX
|
539
|
+
else
|
540
|
+
v = v & I64::I64_MAX
|
541
|
+
end
|
442
542
|
I64(v)
|
443
543
|
else
|
444
544
|
raise EvalError, "unsupported operation to: #{to}"
|
@@ -479,6 +579,25 @@ module Wardite
|
|
479
579
|
I32(v)
|
480
580
|
end
|
481
581
|
|
582
|
+
# @rbs from: Symbol
|
583
|
+
# @rbs to: Symbol
|
584
|
+
# @rbs return: wasmValue
|
585
|
+
def extendN_s(from:, to:)
|
586
|
+
raise EvalError, "unsupported operation"
|
587
|
+
end
|
588
|
+
|
589
|
+
# @rbs to: Symbol
|
590
|
+
# @rbs return: wasmValue
|
591
|
+
def trunc_sat_u(to:)
|
592
|
+
trunc_u(to: to, saturating: true)
|
593
|
+
end
|
594
|
+
|
595
|
+
# @rbs to: Symbol
|
596
|
+
# @rbs return: wasmValue
|
597
|
+
def trunc_sat_s(to:)
|
598
|
+
trunc_s(to: to, saturating: true)
|
599
|
+
end
|
600
|
+
|
482
601
|
def inspect
|
483
602
|
"F32(#{@value})"
|
484
603
|
end
|
@@ -539,27 +658,50 @@ module Wardite
|
|
539
658
|
|
540
659
|
# @see the same as F32
|
541
660
|
# @rbs to: Symbol
|
661
|
+
# @rbs saturating: bool
|
542
662
|
# @rbs return: wasmValue
|
543
|
-
def trunc_s(to:)
|
663
|
+
def trunc_s(to:, saturating: false)
|
544
664
|
v = value.to_i
|
545
665
|
case to
|
546
666
|
when :i32
|
547
667
|
if v >= 0
|
548
|
-
|
668
|
+
i32_signed_max = I32::I32_MAX >> 1
|
669
|
+
if saturating
|
670
|
+
v = i32_signed_max if v > i32_signed_max
|
671
|
+
else
|
672
|
+
v = v & i32_signed_max
|
673
|
+
end
|
674
|
+
I32(v & i32_signed_max)
|
549
675
|
else
|
550
|
-
|
551
|
-
if
|
552
|
-
|
676
|
+
i32_signed_min = -(I32::I32_MAX >> 1) - 1
|
677
|
+
if saturating
|
678
|
+
v = i32_signed_min if v < i32_signed_min
|
679
|
+
else
|
680
|
+
v = v & I32::I32_MAX
|
681
|
+
if (v >> 31).zero?
|
682
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
683
|
+
end
|
553
684
|
end
|
554
685
|
I32(v)
|
555
686
|
end
|
556
687
|
when :i64
|
557
688
|
if v >= 0
|
558
|
-
|
689
|
+
i64_signed_max = I64::I64_MAX >> 1
|
690
|
+
if saturating
|
691
|
+
v = i64_signed_max if v > i64_signed_max
|
692
|
+
else
|
693
|
+
v = v & i64_signed_max
|
694
|
+
end
|
695
|
+
I64(v & i64_signed_max)
|
559
696
|
else
|
560
|
-
|
561
|
-
if
|
562
|
-
|
697
|
+
i64_signed_min = -(I64::I64_MAX >> 1) - 1
|
698
|
+
if saturating
|
699
|
+
v = i64_signed_min if v < i64_signed_min
|
700
|
+
else
|
701
|
+
v = v & I64::I64_MAX
|
702
|
+
if (v >> 63).zero?
|
703
|
+
raise EvalError, "[undefined behavior] detected overflow: #{value}"
|
704
|
+
end
|
563
705
|
end
|
564
706
|
I64(v)
|
565
707
|
end
|
@@ -570,18 +712,31 @@ module Wardite
|
|
570
712
|
|
571
713
|
# @see the same as F32
|
572
714
|
# @rbs to: Symbol
|
715
|
+
# @rbs saturating: bool
|
573
716
|
# @rbs return: wasmValue
|
574
|
-
def trunc_u(to:)
|
717
|
+
def trunc_u(to:, saturating: false)
|
575
718
|
v = value.to_i
|
576
719
|
if v < 0
|
577
|
-
|
720
|
+
if saturating
|
721
|
+
v = 0
|
722
|
+
else
|
723
|
+
raise EvalError, "[undefined behavior] unexpected negative value"
|
724
|
+
end
|
578
725
|
end
|
579
726
|
case to
|
580
727
|
when :i32
|
581
|
-
|
728
|
+
if saturating
|
729
|
+
v = I32::I32_MAX if v > I32::I32_MAX
|
730
|
+
else
|
731
|
+
v = v & I32::I32_MAX
|
732
|
+
end
|
582
733
|
I32(v)
|
583
734
|
when :i64
|
584
|
-
|
735
|
+
if saturating
|
736
|
+
v = I64::I64_MAX if v > I64::I64_MAX
|
737
|
+
else
|
738
|
+
v = v & I64::I64_MAX
|
739
|
+
end
|
585
740
|
I64(v)
|
586
741
|
else
|
587
742
|
raise EvalError, "unsupported operation to: #{to}"
|
@@ -623,6 +778,25 @@ module Wardite
|
|
623
778
|
I64(v)
|
624
779
|
end
|
625
780
|
|
781
|
+
# @rbs from: Symbol
|
782
|
+
# @rbs to: Symbol
|
783
|
+
# @rbs return: wasmValue
|
784
|
+
def extendN_s(from:, to:)
|
785
|
+
raise EvalError, "unsupported operation"
|
786
|
+
end
|
787
|
+
|
788
|
+
# @rbs to: Symbol
|
789
|
+
# @rbs return: wasmValue
|
790
|
+
def trunc_sat_u(to:)
|
791
|
+
trunc_u(to: to, saturating: true)
|
792
|
+
end
|
793
|
+
|
794
|
+
# @rbs to: Symbol
|
795
|
+
# @rbs return: wasmValue
|
796
|
+
def trunc_sat_s(to:)
|
797
|
+
trunc_s(to: to, saturating: true)
|
798
|
+
end
|
799
|
+
|
626
800
|
def inspect
|
627
801
|
"F64(#{@value})"
|
628
802
|
end
|
data/lib/wardite/version.rb
CHANGED
data/lib/wardite.rb
CHANGED
@@ -57,6 +57,22 @@ module Wardite
|
|
57
57
|
@types << Type.new(calltype, rettype)
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
61
|
+
check_data_count
|
62
|
+
end
|
63
|
+
|
64
|
+
# @rbs return: void
|
65
|
+
def check_data_count
|
66
|
+
data_count = self.data_count_section&.count
|
67
|
+
if data_count
|
68
|
+
actual_count = self.data_section&.segments&.size
|
69
|
+
if !actual_count
|
70
|
+
raise LoadError, "invalid data segment count"
|
71
|
+
end
|
72
|
+
if (data_count != actual_count)
|
73
|
+
raise LoadError, "invalid data segment count"
|
74
|
+
end
|
75
|
+
end
|
60
76
|
end
|
61
77
|
|
62
78
|
# @rbs return: ImportSection
|
@@ -129,6 +145,18 @@ module Wardite
|
|
129
145
|
sec
|
130
146
|
end
|
131
147
|
|
148
|
+
# @rbs return: DataCountSection|nil
|
149
|
+
def data_count_section
|
150
|
+
sec = @sections.find{|s| s.code == Const::SectionDataCount }
|
151
|
+
if !sec
|
152
|
+
return nil
|
153
|
+
end
|
154
|
+
if !sec.is_a?(DataCountSection)
|
155
|
+
raise(GenericError, "[BUG] found invalid data section")
|
156
|
+
end
|
157
|
+
sec
|
158
|
+
end
|
159
|
+
|
132
160
|
# @rbs return: FunctionSection|nil
|
133
161
|
def function_section
|
134
162
|
sec = @sections.find{|s| s.code == Const::SectionFunction }
|
@@ -216,7 +244,7 @@ module Wardite
|
|
216
244
|
call_by_index(start_section.func_index)
|
217
245
|
end
|
218
246
|
end
|
219
|
-
|
247
|
+
|
220
248
|
# @rbs name: String|Symbol
|
221
249
|
# @rbs return: bool
|
222
250
|
def callable?(name)
|
@@ -634,6 +662,57 @@ module Wardite
|
|
634
662
|
memory = instance.store.memories[0] || raise("[BUG] no memory")
|
635
663
|
stack.push(I32(memory.grow(delta.value)))
|
636
664
|
|
665
|
+
when :memory_init
|
666
|
+
idx = insn.operand[0]
|
667
|
+
if !idx.is_a?(Integer)
|
668
|
+
raise EvalError, "[BUG] invalid type of operand"
|
669
|
+
end
|
670
|
+
if insn.operand[1] != 0x0
|
671
|
+
$stderr.puts "warning: :memory_init is not ending with 0x00"
|
672
|
+
end
|
673
|
+
data_sec = instance.data_section
|
674
|
+
if !data_sec
|
675
|
+
raise EvalError, "data segment out of range"
|
676
|
+
end
|
677
|
+
data_seg = data_sec.segments[idx]
|
678
|
+
if !data_seg
|
679
|
+
raise EvalError, "data segment out of range"
|
680
|
+
end
|
681
|
+
|
682
|
+
memory = instance.store.memories[0] || raise("[BUG] no memory")
|
683
|
+
length, src_offset, dest_offset = stack.pop, stack.pop, stack.pop
|
684
|
+
if !length.is_a?(I32) || !src_offset.is_a?(I32) || !dest_offset.is_a?(I32)
|
685
|
+
raise EvalError, "invalid stack values"
|
686
|
+
end
|
687
|
+
source = data_seg.data[src_offset.value...(src_offset.value+length.value)]
|
688
|
+
raise EvalError, "invalid source range" if !source
|
689
|
+
memory.data[dest_offset.value...(dest_offset.value+length.value)] = source
|
690
|
+
|
691
|
+
when :memory_copy
|
692
|
+
if insn.operand[0] != 0x0 || insn.operand[1] != 0x0
|
693
|
+
$stderr.puts "warning: :memory_copy is not ending with 0x00"
|
694
|
+
end
|
695
|
+
length, src_offset, dest_offset = stack.pop, stack.pop, stack.pop
|
696
|
+
if !length.is_a?(I32) || !src_offset.is_a?(I32) || !dest_offset.is_a?(I32)
|
697
|
+
raise EvalError, "invalid stack values"
|
698
|
+
end
|
699
|
+
memory = instance.store.memories[0] || raise("[BUG] no memory")
|
700
|
+
source = memory.data[src_offset.value...(src_offset.value+length.value)]
|
701
|
+
raise EvalError, "invalid source range" if !source
|
702
|
+
memory.data[dest_offset.value...(dest_offset.value+length.value)] = source
|
703
|
+
|
704
|
+
when :memory_fill
|
705
|
+
if insn.operand[0] != 0x0
|
706
|
+
$stderr.puts "warning: :memory_fill is not ending with 0x00"
|
707
|
+
end
|
708
|
+
length, byte, dest_offset = stack.pop, stack.pop, stack.pop
|
709
|
+
if !length.is_a?(I32) || !byte.is_a?(I32) || !dest_offset.is_a?(I32)
|
710
|
+
raise EvalError, "invalid stack values"
|
711
|
+
end
|
712
|
+
memory = instance.store.memories[0] || raise("[BUG] no memory")
|
713
|
+
source = byte.value.chr * length.value
|
714
|
+
memory.data[dest_offset.value...(dest_offset.value+length.value)] = source
|
715
|
+
|
637
716
|
else
|
638
717
|
raise "TODO! unsupported #{insn.inspect}"
|
639
718
|
end
|
@@ -905,9 +984,12 @@ module Wardite
|
|
905
984
|
data_section = inst.data_section
|
906
985
|
if data_section
|
907
986
|
data_section.segments.each do |segment|
|
908
|
-
|
987
|
+
if segment.mode != :active
|
988
|
+
next
|
989
|
+
end
|
990
|
+
memory = self.memories[segment.mem_index]
|
909
991
|
if !memory
|
910
|
-
raise GenericError, "invalid memory index: #{segment.
|
992
|
+
raise GenericError, "invalid memory index: #{segment.mem_index}"
|
911
993
|
end
|
912
994
|
|
913
995
|
data_start = segment.offset
|
data/scripts/gen_conv.rb
CHANGED
@@ -39,11 +39,18 @@ module GenConv
|
|
39
39
|
code = DEF.dup
|
40
40
|
method = op.to_s
|
41
41
|
symbol = "#{to.to_s}_#{method}_#{from.to_sym}"
|
42
|
+
extra_kargs = ""
|
42
43
|
|
43
44
|
if method == "extend"
|
44
45
|
method = "extend_"
|
46
|
+
elsif method =~ /^extendN_(u|s)$/
|
47
|
+
suffix = $1
|
48
|
+
from_size = from.to_s.scan(/\d+/).join
|
49
|
+
symbol = "#{to.to_s}_extend_#{from_size}_#{suffix}"
|
50
|
+
extra_kargs = ", from: :#{from.to_s}"
|
45
51
|
elsif method.end_with?("_s") or method.end_with?("_u")
|
46
|
-
core
|
52
|
+
core = method.sub(/_(s|u)$/, "")
|
53
|
+
suffix = method.scan(/_(s|u)$/).join
|
47
54
|
symbol = "#{to.to_s}_#{core}_#{from.to_sym}_#{suffix}"
|
48
55
|
end
|
49
56
|
# NOTE to is as namespace
|
@@ -52,11 +59,14 @@ module GenConv
|
|
52
59
|
code.gsub!(/\$\{TO\}/, to.to_s)
|
53
60
|
code.gsub!(/\$\{TO_CLASS\}/, to_class(to.to_sym))
|
54
61
|
code.gsub!(/\$\{FROM_CLASS\}/, to_class(from.to_sym))
|
62
|
+
code.gsub!(/\$\{EXTRA_KARGS\}/, extra_kargs)
|
55
63
|
return code
|
56
64
|
end
|
57
65
|
|
58
66
|
def self.to_class(typ)
|
59
67
|
{
|
68
|
+
i8: "I32",
|
69
|
+
i16: "I32",
|
60
70
|
i32: "I32",
|
61
71
|
i64: "I64",
|
62
72
|
f32: "F32",
|
@@ -69,7 +79,7 @@ module GenConv
|
|
69
79
|
when :${SYMBOL}
|
70
80
|
from = runtime.stack.pop
|
71
81
|
raise EvalError, "maybe empty or invalid stack" if !from.is_a?(${FROM_CLASS})
|
72
|
-
to = from.${METHOD}(to: :${TO})
|
82
|
+
to = from.${METHOD}(to: :${TO}${EXTRA_KARGS})
|
73
83
|
raise EvalError, "failed to convert type" if !to.is_a?(${TO_CLASS})
|
74
84
|
runtime.stack.push(to)
|
75
85
|
RUBY
|
@@ -7,9 +7,14 @@ module Wardite
|
|
7
7
|
# @see https://pengowray.github.io/wasm-ops/
|
8
8
|
SYMS: Array[Symbol]
|
9
9
|
|
10
|
+
FC_SYMS: Array[Symbol]
|
11
|
+
|
10
12
|
# @rbs return: Hash[Integer, Symbol]
|
11
13
|
def self.table: () -> Hash[Integer, Symbol]
|
12
14
|
|
15
|
+
# @rbs return: Hash[Integer, Symbol]
|
16
|
+
def self.fc_table: () -> Hash[Integer, Symbol]
|
17
|
+
|
13
18
|
attr_accessor namespace: Symbol
|
14
19
|
|
15
20
|
attr_accessor code: Symbol
|
@@ -26,6 +31,10 @@ module Wardite
|
|
26
31
|
# @rbs return: [Symbol, Symbol]
|
27
32
|
def self.to_sym: (String chr) -> [ Symbol, Symbol ]
|
28
33
|
|
34
|
+
# @rbs lower: Integer
|
35
|
+
# @rbs return: [Symbol, Symbol]
|
36
|
+
def self.resolve_fc_sym: (Integer lower) -> [ Symbol, Symbol ]
|
37
|
+
|
29
38
|
# @rbs code: Symbol
|
30
39
|
# @rbs return: Array[Symbol]
|
31
40
|
def self.operand_of: (Symbol code) -> Array[Symbol]
|
@@ -103,7 +103,9 @@ module Wardite
|
|
103
103
|
|
104
104
|
class DataSection < Section
|
105
105
|
class Segment
|
106
|
-
attr_accessor
|
106
|
+
attr_accessor mode: :active | :passive
|
107
|
+
|
108
|
+
attr_accessor mem_index: Integer
|
107
109
|
|
108
110
|
attr_accessor offset: Integer
|
109
111
|
|
@@ -120,6 +122,14 @@ module Wardite
|
|
120
122
|
def initialize: () -> void
|
121
123
|
end
|
122
124
|
|
125
|
+
class DataCountSection < Section
|
126
|
+
attr_accessor count: Integer
|
127
|
+
|
128
|
+
# @rbs count: Integer
|
129
|
+
# @rbs return: void
|
130
|
+
def initialize: (Integer count) -> void
|
131
|
+
end
|
132
|
+
|
123
133
|
class ExportSection < Section
|
124
134
|
class ExportDesc
|
125
135
|
attr_accessor name: String
|
@@ -206,9 +216,17 @@ module Wardite
|
|
206
216
|
# @rbs return: Array[::Wardite::Op]
|
207
217
|
def self.code_body: (StringIO buf) -> Array[::Wardite::Op]
|
208
218
|
|
219
|
+
# @rbs c: String
|
220
|
+
# @rbs buf: StringIO
|
221
|
+
# @rbs return: [Symbol, Symbol]
|
222
|
+
def self.resolve_code: (String c, StringIO buf) -> [ Symbol, Symbol ]
|
223
|
+
|
209
224
|
# @rbs return: DataSection
|
210
225
|
def self.data_section: () -> DataSection
|
211
226
|
|
227
|
+
# @rbs return: DataCountSection
|
228
|
+
def self.data_count_section: () -> DataCountSection
|
229
|
+
|
212
230
|
# @rbs sbuf: StringIO
|
213
231
|
# @rbs return: String
|
214
232
|
def self.fetch_insn_while_end: (StringIO sbuf) -> String
|
@@ -36,7 +36,7 @@ module Wardite
|
|
36
36
|
class I32
|
37
37
|
include ValueHelper
|
38
38
|
|
39
|
-
I32_MAX:
|
39
|
+
I32_MAX: Integer
|
40
40
|
|
41
41
|
# value should be stored as unsigned Integer, even in I32/I64
|
42
42
|
# when we want to access signed value, it'd be done via #value_s
|
@@ -100,6 +100,19 @@ module Wardite
|
|
100
100
|
# @rbs return: wasmValue
|
101
101
|
def reinterpret: (to: Symbol) -> wasmValue
|
102
102
|
|
103
|
+
# @rbs from: Symbol
|
104
|
+
# @rbs to: Symbol
|
105
|
+
# @rbs return: wasmValue
|
106
|
+
def extendN_s: (from: Symbol, to: Symbol) -> wasmValue
|
107
|
+
|
108
|
+
# @rbs to: Symbol
|
109
|
+
# @rbs return: wasmValue
|
110
|
+
def trunc_sat_u: (to: Symbol) -> wasmValue
|
111
|
+
|
112
|
+
# @rbs to: Symbol
|
113
|
+
# @rbs return: wasmValue
|
114
|
+
def trunc_sat_s: (to: Symbol) -> wasmValue
|
115
|
+
|
103
116
|
# I32#inspect shows signed value for convinience
|
104
117
|
def inspect: () -> untyped
|
105
118
|
end
|
@@ -107,7 +120,7 @@ module Wardite
|
|
107
120
|
class I64
|
108
121
|
include ValueHelper
|
109
122
|
|
110
|
-
I64_MAX:
|
123
|
+
I64_MAX: Integer
|
111
124
|
|
112
125
|
attr_accessor value: Integer
|
113
126
|
|
@@ -168,6 +181,19 @@ module Wardite
|
|
168
181
|
# @rbs return: wasmValue
|
169
182
|
def reinterpret: (to: Symbol) -> wasmValue
|
170
183
|
|
184
|
+
# @rbs from: Symbol
|
185
|
+
# @rbs to: Symbol
|
186
|
+
# @rbs return: wasmValue
|
187
|
+
def extendN_s: (from: Symbol, to: Symbol) -> wasmValue
|
188
|
+
|
189
|
+
# @rbs to: Symbol
|
190
|
+
# @rbs return: wasmValue
|
191
|
+
def trunc_sat_u: (to: Symbol) -> wasmValue
|
192
|
+
|
193
|
+
# @rbs to: Symbol
|
194
|
+
# @rbs return: wasmValue
|
195
|
+
def trunc_sat_s: (to: Symbol) -> wasmValue
|
196
|
+
|
171
197
|
# I64#inspect shows signed value
|
172
198
|
def inspect: () -> untyped
|
173
199
|
end
|
@@ -205,14 +231,18 @@ module Wardite
|
|
205
231
|
|
206
232
|
# @todo need more testcase...
|
207
233
|
# @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-s-mathrm-trunc-mathsf-s-m-n-z
|
234
|
+
# @see copy this impl to F64 when changed
|
208
235
|
# @rbs to: Symbol
|
236
|
+
# @rbs saturating: bool
|
209
237
|
# @rbs return: wasmValue
|
210
|
-
def trunc_s: (to: Symbol) -> wasmValue
|
238
|
+
def trunc_s: (to: Symbol, ?saturating: bool) -> wasmValue
|
211
239
|
|
212
240
|
# @see https://webassembly.github.io/spec/core/exec/numerics.html#xref-exec-numerics-op-trunc-u-mathrm-trunc-mathsf-u-m-n-z
|
241
|
+
# @see copy this impl to F64 when changed
|
213
242
|
# @rbs to: Symbol
|
243
|
+
# @rbs sturating: bool
|
214
244
|
# @rbs return: wasmValue
|
215
|
-
def trunc_u: (to: Symbol) -> wasmValue
|
245
|
+
def trunc_u: (to: Symbol, ?saturating: untyped) -> wasmValue
|
216
246
|
|
217
247
|
# @rbs to: Symbol
|
218
248
|
# @rbs return: wasmValue
|
@@ -234,6 +264,19 @@ module Wardite
|
|
234
264
|
# @rbs return: wasmValue
|
235
265
|
def reinterpret: (to: Symbol) -> wasmValue
|
236
266
|
|
267
|
+
# @rbs from: Symbol
|
268
|
+
# @rbs to: Symbol
|
269
|
+
# @rbs return: wasmValue
|
270
|
+
def extendN_s: (from: Symbol, to: Symbol) -> wasmValue
|
271
|
+
|
272
|
+
# @rbs to: Symbol
|
273
|
+
# @rbs return: wasmValue
|
274
|
+
def trunc_sat_u: (to: Symbol) -> wasmValue
|
275
|
+
|
276
|
+
# @rbs to: Symbol
|
277
|
+
# @rbs return: wasmValue
|
278
|
+
def trunc_sat_s: (to: Symbol) -> wasmValue
|
279
|
+
|
237
280
|
def inspect: () -> untyped
|
238
281
|
end
|
239
282
|
|
@@ -270,13 +313,15 @@ module Wardite
|
|
270
313
|
|
271
314
|
# @see the same as F32
|
272
315
|
# @rbs to: Symbol
|
316
|
+
# @rbs saturating: bool
|
273
317
|
# @rbs return: wasmValue
|
274
|
-
def trunc_s: (to: Symbol) -> wasmValue
|
318
|
+
def trunc_s: (to: Symbol, ?saturating: bool) -> wasmValue
|
275
319
|
|
276
320
|
# @see the same as F32
|
277
321
|
# @rbs to: Symbol
|
322
|
+
# @rbs saturating: bool
|
278
323
|
# @rbs return: wasmValue
|
279
|
-
def trunc_u: (to: Symbol) -> wasmValue
|
324
|
+
def trunc_u: (to: Symbol, ?saturating: bool) -> wasmValue
|
280
325
|
|
281
326
|
# @rbs to: Symbol
|
282
327
|
# @rbs return: wasmValue
|
@@ -299,6 +344,19 @@ module Wardite
|
|
299
344
|
# @rbs return: wasmValue
|
300
345
|
def reinterpret: (to: Symbol) -> wasmValue
|
301
346
|
|
347
|
+
# @rbs from: Symbol
|
348
|
+
# @rbs to: Symbol
|
349
|
+
# @rbs return: wasmValue
|
350
|
+
def extendN_s: (from: Symbol, to: Symbol) -> wasmValue
|
351
|
+
|
352
|
+
# @rbs to: Symbol
|
353
|
+
# @rbs return: wasmValue
|
354
|
+
def trunc_sat_u: (to: Symbol) -> wasmValue
|
355
|
+
|
356
|
+
# @rbs to: Symbol
|
357
|
+
# @rbs return: wasmValue
|
358
|
+
def trunc_sat_s: (to: Symbol) -> wasmValue
|
359
|
+
|
302
360
|
def inspect: () -> untyped
|
303
361
|
end
|
304
362
|
end
|
data/sig/generated/wardite.rbs
CHANGED
@@ -26,6 +26,9 @@ module Wardite
|
|
26
26
|
# @rbs &blk: (Instance) -> void
|
27
27
|
def initialize: (Hash[Symbol, Hash[Symbol, wasmCallable]] import_object) { (Instance) -> void } -> untyped
|
28
28
|
|
29
|
+
# @rbs return: void
|
30
|
+
def check_data_count: () -> void
|
31
|
+
|
29
32
|
# @rbs return: ImportSection
|
30
33
|
def import_section: () -> ImportSection
|
31
34
|
|
@@ -44,6 +47,9 @@ module Wardite
|
|
44
47
|
# @rbs return: DataSection|nil
|
45
48
|
def data_section: () -> (DataSection | nil)
|
46
49
|
|
50
|
+
# @rbs return: DataCountSection|nil
|
51
|
+
def data_count_section: () -> (DataCountSection | nil)
|
52
|
+
|
47
53
|
# @rbs return: FunctionSection|nil
|
48
54
|
def function_section: () -> (FunctionSection | nil)
|
49
55
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wardite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uchio Kondo
|
@@ -37,6 +37,9 @@ files:
|
|
37
37
|
- examples/local_set.wat
|
38
38
|
- examples/loop.wat
|
39
39
|
- examples/memory.wat
|
40
|
+
- examples/memory_init.wat
|
41
|
+
- examples/saturate.wat
|
42
|
+
- examples/saturate_u.wat
|
40
43
|
- examples/start.wat
|
41
44
|
- exe/wardite
|
42
45
|
- lib/wardite.rb
|