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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0d5832e8cec120cdc72a68daf9acafb4d571fa2be166a6b912536774278c634
4
- data.tar.gz: 6527a2be1289f3d3e9223cd93497b95c1956593fea6b3430f8cd8293e4ab8e5f
3
+ metadata.gz: 20aa59cedbb81d21c2681737929bb7f29fcf70cd189ca5d0de1ff538fca57782
4
+ data.tar.gz: fed9168236c3d23e377d38e2a6bf175336def008268aa5910215667ff3fac750
5
5
  SHA512:
6
- metadata.gz: 95c24b6c6461b449270eb9a343e613095b2ee7ee587c1ebb88933c6c3c6e65bcba044b48ab51928ff2398b9b11a1d84a4830b78aeb1e67c37448900c2ffa2ddb
7
- data.tar.gz: 4ff3a32bd496162b06df804717a3017e2bcfbdccf25a2727c2c0096cbd6aa12abd119e05b2fdea4db29aaff0f668f42ef856e8b120a685abb0b7c4765c1eb18b
6
+ metadata.gz: '098a4d2d2c25221667307bdf49fa207f682dd0f53e9ee33700cf18790961ce0ea627ed3f8ff7292a4cf55d70bf0c6068ed0b4b03502ec95aedd511c547dac7a0'
7
+ data.tar.gz: 9e1b69ba3cea02e033892ad4bf3fafc456d96d0f4741e8b0a9b6c55d2285cbb7d29fc0f0b2e71b1b35812c905b6281d1c4713c7b9215c5f99b42d94c88a6295b
data/Steepfile CHANGED
@@ -5,6 +5,7 @@ target :lib do
5
5
 
6
6
  library "pp"
7
7
  library "securerandom"
8
+ library "optparse"
8
9
  # configure_code_diagnostics(Steep::Diagnostic::Ruby.strict)
9
10
  end
10
11
 
data/exe/wardite CHANGED
@@ -1,29 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "wardite"
4
- path = ARGV[0]
4
+ require "wardite/cli/cli"
5
5
 
6
- f = File.open(path)
7
- instance = Wardite::BinaryLoader::load_from_buffer(f);
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
- F32(v)
386
+ F64(v)
387
387
  end
388
388
 
389
389
  # @rbs from: Symbol
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Wardite
5
- VERSION = "0.6.1" #: String
5
+ VERSION = "0.8.0" #: String
6
6
  end
@@ -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