wardite 0.5.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89b6c42e1a3f16c39c214eb127c5b87966c0d2933257a1da7fdc96236c6a0f9b
4
- data.tar.gz: 321d62cdddc61c8a342b966b3e4d7b6c01ffbbcb5788a6787fd3490ba96b1430
3
+ metadata.gz: f0d5832e8cec120cdc72a68daf9acafb4d571fa2be166a6b912536774278c634
4
+ data.tar.gz: 6527a2be1289f3d3e9223cd93497b95c1956593fea6b3430f8cd8293e4ab8e5f
5
5
  SHA512:
6
- metadata.gz: 4b8b67989d47775828aca0908794f6b02abdea5ed653d794fa308d437f2d1735997a91dee341cdfa51aa5829aa097ca61dd262dba8479e805d1bbfd540f90ff5
7
- data.tar.gz: 26face977ed4d76232bdee62f64208a22ec824314cb3d479979705fee327a1c9ce72ee960055a0c26db591f932c598b591651170fedf31b36533c52774f05fbe
6
+ metadata.gz: 95c24b6c6461b449270eb9a343e613095b2ee7ee587c1ebb88933c6c3c6e65bcba044b48ab51928ff2398b9b11a1d84a4830b78aeb1e67c37448900c2ffa2ddb
7
+ data.tar.gz: 4ff3a32bd496162b06df804717a3017e2bcfbdccf25a2727c2c0096cbd6aa12abd119e05b2fdea4db29aaff0f668f42ef856e8b120a685abb0b7c4765c1eb18b
data/README.md CHANGED
@@ -70,9 +70,9 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/udzura
70
70
 
71
71
  ## See also
72
72
 
73
- - https://github.com/technohippy/wasmrb?tab=readme-ov-file
73
+ - https://github.com/technohippy/wasmrb
74
74
  - Referencial implementation but no support with WASI
75
- - Wardite aims to support full WASI (previwe 1)
75
+ - Wardite aims to support full WASI (preview 1)
76
76
  - https://github.com/skanehira/chibiwasm
77
77
  - Small and consise implementation in Rust
78
78
  - Wardite was first built upon [its development tutorial](https://skanehira.github.io/writing-a-wasm-runtime-in-rust/). Thanks!
data/Steepfile CHANGED
@@ -4,6 +4,7 @@ target :lib do
4
4
  check "lib"
5
5
 
6
6
  library "pp"
7
+ library "securerandom"
7
8
  # configure_code_diagnostics(Steep::Diagnostic::Ruby.strict)
8
9
  end
9
10
 
data/exe/wardite CHANGED
@@ -1,16 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "wardite"
4
-
5
4
  path = ARGV[0]
6
- method = ARGV[1]
7
- args = ARGV[2..-1] || []
8
5
 
9
6
  f = File.open(path)
10
7
  instance = Wardite::BinaryLoader::load_from_buffer(f);
11
- if !method && instance.runtime.respond_to?(:_start)
12
- instance.runtime._start
8
+ if instance.runtime.respond_to?(:_start) # assumed WASI
9
+ argv = ARGV[1..-1] || []
10
+ instance.wasi.argv = ["wardite"] + argv
11
+ Bundler.with_original_env do
12
+ # instance.store.memories[0].grow(128)
13
+ instance.runtime._start
14
+ end
13
15
  else
16
+ path = ARGV[0]
17
+ method = ARGV[1]
18
+ args = ARGV[2..-1] || []
19
+
14
20
  args = args.map do|a|
15
21
  if a.include? "."
16
22
  a.to_f
@@ -46,16 +46,15 @@ module Wardite
46
46
 
47
47
  # @rbs @@table: Hash[Integer, Symbol] | nil
48
48
  @@table = nil
49
- # @rbs @@table: Hash[Integer, Symbol] | nil
49
+ # @rbs @@fc_table: Hash[Integer, Symbol] | nil
50
50
  @@fc_table = nil
51
51
 
52
52
  # @rbs return: Hash[Integer, Symbol]
53
53
  def self.table
54
54
  return @@table if @@table != nil
55
- @@table = {}.tap do |ha|
56
- SYMS.each_with_index do |sym, i|
57
- ha[i] = sym
58
- end
55
+ @@table = {} #: Hash[Integer, Symbol] | nil
56
+ SYMS.each_with_index do |sym, i|
57
+ @@table[i] = sym
59
58
  end
60
59
  @@table
61
60
  end
@@ -63,10 +62,9 @@ module Wardite
63
62
  # @rbs return: Hash[Integer, Symbol]
64
63
  def self.fc_table
65
64
  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
65
+ @@fc_table = {} #: Hash[Integer, Symbol] | nil
66
+ FC_SYMS.each_with_index do |sym, i|
67
+ @@fc_table[i] = sym
70
68
  end
71
69
  @@fc_table
72
70
  end
data/lib/wardite/load.rb CHANGED
@@ -250,7 +250,7 @@ module Wardite
250
250
  # @rbs self.@buf: File|StringIO
251
251
 
252
252
  # @rbs buf: File|StringIO
253
- # @rbs import_object: Hash[Symbol, Hash[Symbol, wasmCallable]]
253
+ # @rbs import_object: Hash[Symbol, wasmModuleSrc]
254
254
  # @rbs enable_wasi: boolish
255
255
  # @rbs return: Instance
256
256
  def self.load_from_buffer(buf, import_object: {}, enable_wasi: true)
@@ -259,14 +259,19 @@ module Wardite
259
259
  version = preamble
260
260
  sections_ = sections
261
261
 
262
+ wasi_env = nil
262
263
  if enable_wasi
264
+ require "wardite/wasi"
263
265
  wasi_env = Wardite::WasiSnapshotPreview1.new
264
- import_object[:wasi_snapshot_preview1] = wasi_env.to_module
266
+ import_object[:wasi_snapshot_preview1] = wasi_env
265
267
  end
266
268
 
267
269
  return Instance.new(import_object) do |i|
268
270
  i.version = version
269
271
  i.sections = sections_
272
+ if enable_wasi
273
+ i.wasi = wasi_env
274
+ end
270
275
  end
271
276
  end
272
277
 
@@ -358,7 +363,7 @@ module Wardite
358
363
  end
359
364
 
360
365
  arglen = fetch_uleb128(sbuf)
361
- arg = []
366
+ arg = [] #: Array[Symbol]
362
367
  arglen.times do
363
368
  case ty = assert_read(sbuf, 1)&.ord
364
369
  when 0x7f
@@ -376,7 +381,7 @@ module Wardite
376
381
  dest.defined_types << arg
377
382
 
378
383
  retlen = fetch_uleb128(sbuf)
379
- ret = []
384
+ ret = [] #: Array[Symbol]
380
385
  retlen.times do
381
386
  case ty = assert_read(sbuf, 1)&.ord
382
387
  when 0x7f
@@ -482,7 +487,7 @@ module Wardite
482
487
  offset = decode_expr(ops)
483
488
  dest.table_offsets << offset
484
489
 
485
- elms = []
490
+ elms = [] #: Array[Integer]
486
491
  elen = fetch_uleb128(sbuf)
487
492
  elen.times do |i|
488
493
  index = fetch_uleb128(sbuf)
@@ -585,8 +590,8 @@ module Wardite
585
590
  $stderr.puts "warning: instruction not ended with inst end(0x0b): 0x0#{last_code.ord}"
586
591
  end
587
592
  cbuf = StringIO.new(code)
588
- locals_count = []
589
- locals_type = []
593
+ locals_count = [] #: Array[Integer]
594
+ locals_type = [] #: Array[Symbol]
590
595
  locals_len = fetch_uleb128(cbuf)
591
596
  locals_len.times do
592
597
  type_count = fetch_uleb128(cbuf)
@@ -610,7 +615,7 @@ module Wardite
610
615
  # @rbs buf: StringIO
611
616
  # @rbs return: Array[::Wardite::Op]
612
617
  def self.code_body(buf)
613
- dest = []
618
+ dest = [] #: Array[Op]
614
619
  while c = buf.read(1)
615
620
  namespace, code = resolve_code(c, buf)
616
621
  operand_types = Op.operand_of(code)
@@ -855,7 +860,7 @@ module Wardite
855
860
  # @rbs code: Integer
856
861
  # @rbs return: nil
857
862
  def self.unimplemented_skip_section(code)
858
- $stderr.puts "warning: unimplemented section: 0x0#{code}"
863
+ $stderr.puts "warning: unimplemented section: 0x0#{code}" if ENV['WARN_UNIMPLEMENTED_SECTION']
859
864
  size = fetch_uleb128(@buf)
860
865
  @buf.read(size)
861
866
  nil
@@ -42,7 +42,7 @@ module Wardite
42
42
  case inst&.code
43
43
  when nil
44
44
  raise EvalError, "end op not found"
45
- when :if
45
+ when :if, :block, :loop
46
46
  depth += 1
47
47
  when :else
48
48
  if depth == 0
data/lib/wardite/value.rb CHANGED
@@ -8,21 +8,13 @@ module Wardite
8
8
  # @rbs value: Integer
9
9
  # @rbs return: I32
10
10
  def I32(value)
11
- if value < 0
12
- # $stderr.puts "trace: negative i32 value #{value} is passed, convert to unsigned"
13
- value = as_u32(value)
14
- end
15
- I32.new.tap{|i| i.value = value & I32::I32_MAX }
11
+ I32.cached_or_initialize(value & I32::I32_MAX)
16
12
  end
17
13
 
18
14
  # @rbs value: Integer
19
15
  # @rbs return: I64
20
16
  def I64(value)
21
- if value < 0
22
- # $stderr.puts "trace: negative i64 value #{value} is passed, convert to unsigned"
23
- value = as_u64(value)
24
- end
25
- I64.new.tap{|i| i.value = value & I64::I64_MAX }
17
+ I64.new(value & I64::I64_MAX)
26
18
  end
27
19
 
28
20
  # @rbs value: Float
@@ -36,19 +28,6 @@ module Wardite
36
28
  def F64(value)
37
29
  F64.new.tap{|i| i.value = value }
38
30
  end
39
-
40
- private
41
- # @rbs value: Integer
42
- # @rbs return: Integer
43
- def as_u32(value)
44
- ((-value) ^ I32::I32_MAX) + 1
45
- end
46
-
47
- # @rbs value: Integer
48
- # @rbs return: Integer
49
- def as_u64(value)
50
- ((-value) ^ I64::I64_MAX) + 1
51
- end
52
31
  end
53
32
 
54
33
  extend ValueHelper
@@ -61,6 +40,21 @@ module Wardite
61
40
  # when we want to access signed value, it'd be done via #value_s
62
41
  attr_accessor :value #: Integer
63
42
 
43
+ # @rbs!
44
+ # @@i32_object_pool: Hash[Integer, I32]
45
+ @@i32_object_pool = {} #: Hash[Integer, I32]
46
+
47
+ # @rbs value: Integer
48
+ # @rbs return: I32
49
+ def self.cached_or_initialize(value)
50
+ @@i32_object_pool[value] || I32.new(value)
51
+ end
52
+
53
+ # @rbs value: Integer
54
+ def initialize(value=0)
55
+ @value = value
56
+ end
57
+
64
58
  # @rbs str: String
65
59
  # @rbs size: Integer|nil
66
60
  # @rbs signed: bool
@@ -241,6 +235,12 @@ module Wardite
241
235
  def ==(other)
242
236
  return self.class == other.class && self.value == other.value
243
237
  end
238
+
239
+ (0..64).each do |value|
240
+ @@i32_object_pool[value] = I32.new(value)
241
+ end
242
+ value = -1 & I32::I32_MAX
243
+ @@i32_object_pool[value] = I32.new(value)
244
244
  end
245
245
 
246
246
  class I64
@@ -250,6 +250,11 @@ module Wardite
250
250
 
251
251
  attr_accessor :value #: Integer
252
252
 
253
+ # @rbs value: Integer
254
+ def initialize(value=0)
255
+ @value = value
256
+ end
257
+
253
258
  # @rbs str: String
254
259
  # @rbs size: Integer|nil
255
260
  # @rbs signed: bool
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Wardite
5
- VERSION = "0.5.1" #: String
5
+ VERSION = "0.6.1" #: String
6
6
  end
@@ -0,0 +1,129 @@
1
+ # rbs_inline: enabled
2
+
3
+ module Wardite
4
+ module Wasi
5
+ EACCES = 2
6
+ EAGAIN = 6
7
+ EBADF = 8
8
+ EEXIST = 20
9
+ EFAULT = 21
10
+ EINTR = 27
11
+ EINVAL = 28
12
+ EIO = 29
13
+ EISDIR = 31
14
+ ELOOP = 32
15
+ ENAMETOOLONG = 37
16
+ ENOENT = 44
17
+ ENOSYS = 52
18
+ ENOTDIR = 54
19
+ ERANGE = 68
20
+ ENOTEMPTY = 55
21
+ ENOTSOCK = 57
22
+ ENOTSUP = 58
23
+ EPERM = 63
24
+ EROFS = 69
25
+
26
+ FILETYPE_UNKNOWN = 0
27
+ FILETYPE_BLOCK_DEVICE = 1 #: Integer
28
+ FILETYPE_CHARACTER_DEVICE = 2 #: Integer
29
+ FILETYPE_DIRECTORY = 3 #: Integer
30
+ FILETYPE_REGULAR_FILE = 4 #: Integer
31
+ FILETYPE_SOCKET_DGRAM = 5 #: Integer
32
+ FILETYPE_SOCKET_STREAM = 6 #: Integer
33
+ FILETYPE_SYMBOLIC_LINK = 7 #: Integer
34
+
35
+ FD_APPEND = 1 << 0 #: Integer
36
+ FD_DSYNC = 1 << 1 #: Integer
37
+ FD_NONBLOCK = 1 << 2 #: Integer
38
+ FD_RSYNC = 1 << 3 #: Integer
39
+ FD_SYNC = 1 << 4 #: Integer
40
+
41
+ RIGHT_FD_DATASYNC = 1 << 0
42
+ RIGHT_FD_READ = 1 << 1
43
+ RIGHT_FD_SEEK = 1 << 2
44
+ RIGHT_FDSTAT_SET_FLAGS = 1 << 3
45
+ RIGHT_FD_SYNC = 1 << 4
46
+ RIGHT_FD_TELL = 1 << 5
47
+ RIGHT_FD_WRITE = 1 << 6
48
+ RIGHT_FD_ADVISE = 1 << 7
49
+ RIGHT_FD_ALLOCATE = 1 << 8
50
+ RIGHT_PATH_CREATE_DIRECTORY = 1 << 9
51
+ RIGHT_PATH_CREATE_FILE = 1 << 10
52
+ RIGHT_PATH_LINK_SOURCE = 1 << 11
53
+ RIGHT_PATH_LINK_TARGET = 1 << 12
54
+ RIGHT_PATH_OPEN = 1 << 13
55
+ RIGHT_FD_READDIR = 1 << 14
56
+ RIGHT_PATH_READLINK = 1 << 15
57
+ RIGHT_PATH_RENAME_SOURCE = 1 << 16
58
+ RIGHT_PATH_RENAME_TARGET = 1 << 17
59
+ RIGHT_PATH_FILESTAT_GET = 1 << 18
60
+ RIGHT_PATH_FILESTAT_SET_SIZE = 1 << 19
61
+ RIGHT_PATH_FILESTAT_SET_TIMES = 1 << 20
62
+ RIGHT_FD_FILESTAT_GET = 1 << 21
63
+ RIGHT_FD_FILESTAT_SET_SIZE = 1 << 22
64
+ RIGHT_FD_FILESTAT_SET_TIMES = 1 << 23
65
+ RIGHT_PATH_SYMLINK = 1 << 24
66
+ RIGHT_PATH_REMOVE_DIRECTORY = 1 << 25
67
+ RIGHT_PATH_UNLINK_FILE = 1 << 26
68
+ RIGHT_POLL_FD_READWRITE = 1 << 27
69
+ RIGHT_SOCK_SHUTDOWN = 1 << 28
70
+
71
+ RIGHT_FILE_RIGHT_BASE = RIGHT_FD_DATASYNC |
72
+ RIGHT_FD_READ |
73
+ RIGHT_FD_SEEK |
74
+ RIGHT_FDSTAT_SET_FLAGS |
75
+ RIGHT_FD_SYNC |
76
+ RIGHT_FD_TELL |
77
+ RIGHT_FD_WRITE |
78
+ RIGHT_FD_ADVISE |
79
+ RIGHT_FD_ALLOCATE |
80
+ RIGHT_FD_FILESTAT_GET |
81
+ RIGHT_FD_FILESTAT_SET_SIZE |
82
+ RIGHT_FD_FILESTAT_SET_TIMES |
83
+ RIGHT_POLL_FD_READWRITE
84
+
85
+ RIGHT_DIR_RIGHT_BASE = RIGHT_FD_DATASYNC |
86
+ RIGHT_FDSTAT_SET_FLAGS |
87
+ RIGHT_FD_SYNC |
88
+ RIGHT_PATH_CREATE_DIRECTORY |
89
+ RIGHT_PATH_CREATE_FILE |
90
+ RIGHT_PATH_LINK_SOURCE |
91
+ RIGHT_PATH_LINK_TARGET |
92
+ RIGHT_PATH_OPEN |
93
+ RIGHT_FD_READDIR |
94
+ RIGHT_PATH_READLINK |
95
+ RIGHT_PATH_RENAME_SOURCE |
96
+ RIGHT_PATH_RENAME_TARGET |
97
+ RIGHT_PATH_FILESTAT_GET |
98
+ RIGHT_PATH_FILESTAT_SET_SIZE |
99
+ RIGHT_PATH_FILESTAT_SET_TIMES |
100
+ RIGHT_FD_FILESTAT_GET |
101
+ RIGHT_FD_FILESTAT_SET_TIMES |
102
+ RIGHT_PATH_SYMLINK |
103
+ RIGHT_PATH_REMOVE_DIRECTORY |
104
+ RIGHT_PATH_UNLINK_FILE
105
+
106
+ # @rbs mode_str: String
107
+ # @rbs return: Integer
108
+ def self.to_ftype(mode_str)
109
+ case mode_str
110
+ when "file"
111
+ FILETYPE_REGULAR_FILE
112
+ when "directory"
113
+ FILETYPE_DIRECTORY
114
+ when "characterSpecial"
115
+ FILETYPE_CHARACTER_DEVICE
116
+ when "blockSpecial"
117
+ FILETYPE_BLOCK_DEVICE
118
+ when "fifo"
119
+ FILETYPE_UNKNOWN
120
+ when "link"
121
+ FILETYPE_SYMBOLIC_LINK
122
+ when "socket"
123
+ FILETYPE_SOCKET_STREAM # TODO: check UDP
124
+ else
125
+ FILETYPE_UNKNOWN
126
+ end
127
+ end
128
+ end
129
+ end