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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f92001daa1c57ae535fd1556fabee90a61dbe741e4e5b9f313c26e5d75d68b3e
4
- data.tar.gz: 237df98e70875e1b6e69fbf0019cc298c3df26fa69cd4e62df8a04eaeff37522
3
+ metadata.gz: 2d2b7f37620b7290c9a4c1fc558024d87cb7ad73bf217c7f7abbda3e6dfda266
4
+ data.tar.gz: c239d24ee56a9dd80084abc11dcffad7a40edbc2c4644146c3cf91fa5b393ddd
5
5
  SHA512:
6
- metadata.gz: 94b5d318cebff3c8d87ea03fa0c5489ece3ef26ca7fcd6e6324febaf55a63f0a9ecb0a76d01b5adf5712737d8daf79ac55f5e2149ff8f85612acbaee1a2ace8c
7
- data.tar.gz: c5991f43b9a62a7df87f23ec71350a77bf9493ccd083c6d0dba596c55976460e0c89625294048389a5fec1e35826bfbddd205718b45e04353b8e1627ccc4bb57
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
+ )
@@ -0,0 +1,8 @@
1
+ (module
2
+ (global $big (mut f64) (f64.const 50000000000.0))
3
+ (func $main (result i32)
4
+ global.get $big
5
+ i32.trunc_sat_f64_s
6
+ )
7
+ (export "saturate" (func $main))
8
+ )
@@ -0,0 +1,9 @@
1
+ (module
2
+ (global $big (mut f64) (f64.const 50000000000.0))
3
+ (func $main (result i64)
4
+ global.get $big
5
+ i32.trunc_sat_f64_u
6
+ i64.extend_i32_u
7
+ )
8
+ (export "saturate" (func $main))
9
+ )
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 = 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
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)
@@ -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
- @@table = nil
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, :u8]
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 :flags #: Integer
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 = Op.to_sym(c)
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
- mem_index = fetch_uleb128(sbuf)
665
- code = fetch_insn_while_end(sbuf)
666
- ops = code_body(StringIO.new(code))
667
- offset = decode_expr(ops)
668
-
669
- len = fetch_uleb128(sbuf)
670
- data = sbuf.read len
671
- if !data
672
- raise LoadError, "buffer too short"
673
- end
674
-
675
- segment = DataSection::Segment.new do |seg|
676
- seg.flags = mem_index
677
- seg.offset = offset
678
- seg.data = data
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
- # TODO: floats
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
- I32(v & (I32::I32_MAX >> 1))
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
- v = v & I32::I32_MAX
408
- if (v >> 31).zero?
409
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
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
- I64(v & (I64::I64_MAX >> 1))
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
- v = v & I64::I64_MAX
418
- if (v >> 31).zero?
419
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
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
- raise EvalError, "[undefined behavior] unexpected negative value"
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
- v = v & I32::I32_MAX
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
- v = v & I64::I64_MAX
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
- I32(v & (I32::I32_MAX >> 1))
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
- v = v & I32::I32_MAX
551
- if (v >> 31).zero?
552
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
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
- I64(v & (I64::I64_MAX >> 1))
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
- v = v & I64::I64_MAX
561
- if (v >> 31).zero?
562
- raise EvalError, "[undefined behavior] detected overflow: #{value}"
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
- raise EvalError, "[undefined behavior] unexpected negative value"
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
- v = v & I32::I32_MAX
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
- v = v & I64::I64_MAX
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
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Wardite
5
- VERSION = "0.3.0" #: String
5
+ VERSION = "0.4.0" #: String
6
6
  end
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
- memory = self.memories[segment.flags]
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.flags}"
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, suffix = *(method.split("_")[0..1])
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
@@ -28,6 +28,8 @@ module Wardite
28
28
  SectionCode: Integer
29
29
 
30
30
  SectionData: Integer
31
+
32
+ SectionDataCount: Integer
31
33
  end
32
34
 
33
35
  include Const
@@ -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 flags: Integer
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: untyped
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: untyped
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
@@ -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.3.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