wardite 0.6.1 → 0.8.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/Steepfile +1 -0
- data/exe/wardite +3 -25
- data/lib/wardite/cli/cli.rb +135 -0
- data/lib/wardite/value.rb +1 -1
- data/lib/wardite/version.rb +1 -1
- data/lib/wardite/wasi/consts.rb +7 -0
- data/lib/wardite/wasi/dirent_cache.rb +87 -0
- data/lib/wardite/wasi/preopens.rb +17 -0
- data/lib/wardite/wasi.rb +457 -17
- data/lib/wardite.rb +8 -1
- data/rbs_collection.lock.yaml +204 -0
- data/rbs_collection.yaml +18 -0
- data/sig/bundler.rbs +3 -0
- data/sig/generated/wardite/cli/cli.rbs +52 -0
- data/sig/generated/wardite/wasi/consts.rbs +10 -0
- data/sig/generated/wardite/wasi/dirent_cache.rbs +42 -0
- data/sig/generated/wardite/wasi/preopens.rbs +15 -0
- data/sig/generated/wardite/wasi.rbs +102 -2
- data/sig/generated/wardite.rbs +5 -1
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20aa59cedbb81d21c2681737929bb7f29fcf70cd189ca5d0de1ff538fca57782
|
4
|
+
data.tar.gz: fed9168236c3d23e377d38e2a6bf175336def008268aa5910215667ff3fac750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '098a4d2d2c25221667307bdf49fa207f682dd0f53e9ee33700cf18790961ce0ea627ed3f8ff7292a4cf55d70bf0c6068ed0b4b03502ec95aedd511c547dac7a0'
|
7
|
+
data.tar.gz: 9e1b69ba3cea02e033892ad4bf3fafc456d96d0f4741e8b0a9b6c55d2285cbb7d29fc0f0b2e71b1b35812c905b6281d1c4713c7b9215c5f99b42d94c88a6295b
|
data/Steepfile
CHANGED
data/exe/wardite
CHANGED
@@ -1,29 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "wardite"
|
4
|
-
|
4
|
+
require "wardite/cli/cli"
|
5
5
|
|
6
|
-
|
7
|
-
|
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
|
15
|
-
else
|
16
|
-
path = ARGV[0]
|
17
|
-
method = ARGV[1]
|
18
|
-
args = ARGV[2..-1] || []
|
19
|
-
|
20
|
-
args = args.map do|a|
|
21
|
-
if a.include? "."
|
22
|
-
a.to_f
|
23
|
-
else
|
24
|
-
a.to_i
|
25
|
-
end
|
26
|
-
end
|
27
|
-
ret = instance.runtime.call(method, args)
|
28
|
-
$stderr.puts "return value: #{ret.inspect}"
|
29
|
-
end
|
6
|
+
cli = Wardite::Cli::Cli.new(ARGV)
|
7
|
+
cli.run
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
require "optparse"
|
3
|
+
|
4
|
+
module Wardite
|
5
|
+
module Cli
|
6
|
+
class Cli
|
7
|
+
# @rbs @args: Array[String]
|
8
|
+
|
9
|
+
attr_reader :invoke #: String?
|
10
|
+
attr_reader :mapdir #: String?
|
11
|
+
attr_reader :file #: String
|
12
|
+
attr_reader :memsize #: Integer
|
13
|
+
attr_reader :wasi #: bool
|
14
|
+
attr_reader :yjit #: bool
|
15
|
+
|
16
|
+
# @rbs args: Array[String]
|
17
|
+
# @rbs return: void
|
18
|
+
def initialize(args)
|
19
|
+
@invoke = @mapdir = nil
|
20
|
+
@wasi = true # default to true
|
21
|
+
@yjit = false
|
22
|
+
@memsize = 1
|
23
|
+
options = OptionParser.new do |opts|
|
24
|
+
opts.version = Wardite::VERSION
|
25
|
+
opts.on("--invoke [fnname]", "Invoke the function") { |v|
|
26
|
+
@invoke = v
|
27
|
+
}
|
28
|
+
opts.on("--mapdir [dirs]", "Map the directory") { |v|
|
29
|
+
@mapdir = v
|
30
|
+
}
|
31
|
+
opts.on("--memsize [size_in_bytes]", "Initial memory size") { |v|
|
32
|
+
@memsize = (v.to_i / (64 * 1024).to_f).ceil.to_i
|
33
|
+
}
|
34
|
+
opts.on("--no-wasi", "Disable WASI feature") {|_v|
|
35
|
+
@wasi = false
|
36
|
+
}
|
37
|
+
opts.on("--yjit", "Enable yjit if available; setting WARDITE_YJIT_ON=1 has the same effect") {|_v|
|
38
|
+
@yjit = true
|
39
|
+
}
|
40
|
+
opts.on("FILE.wasm") { }
|
41
|
+
end
|
42
|
+
options.parse!(args)
|
43
|
+
@file = args[0] || raise("require file argument")
|
44
|
+
@args = (args[1..-1] || [])
|
45
|
+
@args.unshift if @args[0] == '--'
|
46
|
+
|
47
|
+
if (yjit || ENV["WARDITE_YJIT_ON"] == "1") && (defined? RubyVM::YJIT)
|
48
|
+
RubyVM::YJIT.enable
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @rbs return: Array[Integer | Float]
|
53
|
+
# @rbs %a{pure}
|
54
|
+
def args
|
55
|
+
@args.map do |a|
|
56
|
+
if a.include? "."
|
57
|
+
a.to_f
|
58
|
+
else
|
59
|
+
a.to_i
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @rbs return: ::Wardite::Instance
|
65
|
+
def new_instance
|
66
|
+
f = File.open(file)
|
67
|
+
ins = Wardite::BinaryLoader::load_from_buffer(f, enable_wasi: wasi);
|
68
|
+
if memsize > 1
|
69
|
+
ins.store.memories[0].grow(memsize)
|
70
|
+
end
|
71
|
+
ins
|
72
|
+
end
|
73
|
+
|
74
|
+
# @rbs return: void
|
75
|
+
def run
|
76
|
+
if invoke
|
77
|
+
invoke_function
|
78
|
+
else
|
79
|
+
if wasi
|
80
|
+
invoke_wasi
|
81
|
+
return
|
82
|
+
end
|
83
|
+
raise("requires function name to invoke")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# @rbs return: void
|
88
|
+
def invoke_function
|
89
|
+
unless invoke
|
90
|
+
raise "--invoke not set"
|
91
|
+
end
|
92
|
+
instance = new_instance
|
93
|
+
ret = instance.runtime.call(invoke, args)
|
94
|
+
$stderr.puts "return value: #{ret.inspect}"
|
95
|
+
end
|
96
|
+
|
97
|
+
# @rbs return: void
|
98
|
+
def invoke_wasi
|
99
|
+
instance = new_instance #: ::Wardite::Instance
|
100
|
+
unless instance.wasi
|
101
|
+
raise "WASI not activated"
|
102
|
+
end
|
103
|
+
instance.wasi.argv = ["wardite"] + @args
|
104
|
+
if mapdir && mount_dst && mount_src
|
105
|
+
# TODO: support multiple mapdir
|
106
|
+
instance.wasi.mapdir[mount_dst] = mount_src
|
107
|
+
instance.wasi.set_preopened_dir(mount_dst, mount_src)
|
108
|
+
end
|
109
|
+
|
110
|
+
if defined? Bundler
|
111
|
+
Bundler.with_original_env do
|
112
|
+
instance.runtime._start
|
113
|
+
end
|
114
|
+
else
|
115
|
+
instance.runtime._start
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# @rbs return: String?
|
120
|
+
# @rbs %a{pure}
|
121
|
+
def mount_src
|
122
|
+
mapdir&.split(":")&.first
|
123
|
+
end
|
124
|
+
|
125
|
+
# @rbs return: String?
|
126
|
+
# @rbs %a{pure}
|
127
|
+
def mount_dst
|
128
|
+
m = mapdir&.split(":")
|
129
|
+
if m
|
130
|
+
m.size == 2 ? m[1] : m[0]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/lib/wardite/value.rb
CHANGED
@@ -383,7 +383,7 @@ module Wardite
|
|
383
383
|
raise EvalError, "unsupported operation" if to != :f64
|
384
384
|
v = [value].pack("L!").unpack("d")[0]
|
385
385
|
raise EvalError, "[BUG] String#unpack is broke, really?" if !v.is_a?(Float)
|
386
|
-
|
386
|
+
F64(v)
|
387
387
|
end
|
388
388
|
|
389
389
|
# @rbs from: Symbol
|
data/lib/wardite/version.rb
CHANGED
data/lib/wardite/wasi/consts.rb
CHANGED
@@ -103,6 +103,13 @@ module Wardite
|
|
103
103
|
RIGHT_PATH_REMOVE_DIRECTORY |
|
104
104
|
RIGHT_PATH_UNLINK_FILE
|
105
105
|
|
106
|
+
LOOKUP_SYMLINK_FOLLOW = 1 << 0
|
107
|
+
|
108
|
+
O_CREAT = 1 << 0
|
109
|
+
O_DIRECTORY = 1 << 1
|
110
|
+
O_EXCL = 1 << 2
|
111
|
+
O_TRUNC = 1 << 3
|
112
|
+
|
106
113
|
# @rbs mode_str: String
|
107
114
|
# @rbs return: Integer
|
108
115
|
def self.to_ftype(mode_str)
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
3
|
+
module Wardite
|
4
|
+
module Wasi
|
5
|
+
class Dirent
|
6
|
+
attr_reader :path #: String
|
7
|
+
attr_reader :ino #: Integer
|
8
|
+
attr_reader :type #: Integer
|
9
|
+
|
10
|
+
# @rbs path: String
|
11
|
+
# @rbs ino: Integer
|
12
|
+
# @rbs type: Integer
|
13
|
+
# @rbs return: void
|
14
|
+
def initialize(path, ino, type)
|
15
|
+
@path = path
|
16
|
+
@ino = ino
|
17
|
+
@type = type
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class DirentCache
|
22
|
+
attr_reader :entries #: Array[Dirent]
|
23
|
+
attr_accessor :eof #: bool
|
24
|
+
|
25
|
+
# @rbs path: String
|
26
|
+
# @rbs return: void
|
27
|
+
def initialize(path)
|
28
|
+
@entries = []
|
29
|
+
Dir.entries(path).sort.each do |entry|
|
30
|
+
case entry
|
31
|
+
when "."
|
32
|
+
@entries << Dirent.new(entry, File.stat(path).ino, FILETYPE_DIRECTORY)
|
33
|
+
when ".."
|
34
|
+
@entries << Dirent.new(entry, 0, FILETYPE_DIRECTORY)
|
35
|
+
else
|
36
|
+
full_path = File.join(path, entry)
|
37
|
+
type = case File.ftype(full_path)
|
38
|
+
when "directory" then FILETYPE_DIRECTORY
|
39
|
+
when "file" then FILETYPE_REGULAR_FILE
|
40
|
+
when "link" then FILETYPE_SYMBOLIC_LINK
|
41
|
+
else FILETYPE_UNKNOWN
|
42
|
+
end
|
43
|
+
@entries << Dirent.new(entry, File.stat(full_path).ino, type)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
@eof = false
|
48
|
+
end
|
49
|
+
|
50
|
+
# @rbs buf_len: Integer
|
51
|
+
# @rbs cookie: Integer
|
52
|
+
# @rbs return: [String, bool]
|
53
|
+
def fetch_entries_binary(buf_len, cookie)
|
54
|
+
# d_next is the index of the next file in the list, so it should
|
55
|
+
# always be one higher than the requested cookie.
|
56
|
+
d_next = cookie + 1
|
57
|
+
buf = ""
|
58
|
+
entries_slice = entries[cookie..-1]
|
59
|
+
return "", false if entries_slice.nil? || entries_slice.empty?
|
60
|
+
|
61
|
+
entries_slice.each do |entry|
|
62
|
+
data = make_dirent_pack1(d_next, entry.ino, entry.path.size, entry.type, entry.path)
|
63
|
+
if buf.size + data.size > buf_len
|
64
|
+
# truncated
|
65
|
+
return buf, true
|
66
|
+
end
|
67
|
+
buf += data
|
68
|
+
d_next += 1
|
69
|
+
end
|
70
|
+
|
71
|
+
return buf, false
|
72
|
+
end
|
73
|
+
|
74
|
+
# @rbs d_next: Integer
|
75
|
+
# @rbs ino: Integer
|
76
|
+
# @rbs name_len: Integer
|
77
|
+
# @rbs type: Integer
|
78
|
+
# @rbs name: String
|
79
|
+
# @rbs return: String
|
80
|
+
def make_dirent_pack1(d_next, ino, name_len, type, name)
|
81
|
+
data = [d_next, ino, name_len, type].pack("Q! Q! I! I!")
|
82
|
+
data += name
|
83
|
+
data
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
3
|
+
module Wardite
|
4
|
+
module Wasi
|
5
|
+
class PreopenedDir
|
6
|
+
attr_reader :path #: String
|
7
|
+
attr_reader :guest_path #: String
|
8
|
+
attr_reader :fd #: Integer
|
9
|
+
|
10
|
+
def initialize(path, guest_path, fd)
|
11
|
+
@path = path
|
12
|
+
@guest_path = guest_path
|
13
|
+
@fd = fd
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|