Class: Wardite::WasiSnapshotPreview1
- Inherits:
-
Object
- Object
- Wardite::WasiSnapshotPreview1
- Includes:
- ValueHelper, WasmModule
- Defined in:
- lib/wardite/wasi.rb
Instance Attribute Summary collapse
-
#argv ⇒ Object
: Array.
-
#fd_table ⇒ Object
: Array.
-
#mapdir ⇒ Object
: Hash[String, String].
Instance Method Summary collapse
- #args_get(store, args) ⇒ Object
- #args_sizes_get(store, args) ⇒ Object
- #clock_time_get(store, args) ⇒ Object
- #environ_get(store, args) ⇒ Object
- #environ_sizes_get(store, args) ⇒ Object
- #fd_fdstat_get(store, args) ⇒ Object
- #fd_filestat_get(store, args) ⇒ Object
- #fd_prestat_get(store, args) ⇒ Object
- #fd_read(store, args) ⇒ Object
- #fd_write(store, args) ⇒ Object
-
#initialize(argv: [], mapdir: {}) ⇒ WasiSnapshotPreview1
constructor
A new instance of WasiSnapshotPreview1.
- #proc_exit(store, args) ⇒ Object
- #random_get(store, args) ⇒ Object
Methods included from WasmModule
Methods included from ValueHelper
Constructor Details
#initialize(argv: [], mapdir: {}) ⇒ WasiSnapshotPreview1
Returns a new instance of WasiSnapshotPreview1.
20 21 22 23 24 25 26 27 28 |
# File 'lib/wardite/wasi.rb', line 20 def initialize(argv: [], mapdir: {}) @fd_table = [ STDIN, STDOUT, STDERR, ] @argv = argv @mapdir = mapdir end |
Instance Attribute Details
#fd_table ⇒ Object
: Array
13 14 15 |
# File 'lib/wardite/wasi.rb', line 13 def fd_table @fd_table end |
#mapdir ⇒ Object
: Hash[String, String]
15 16 17 |
# File 'lib/wardite/wasi.rb', line 15 def mapdir @mapdir end |
Instance Method Details
#args_get(store, args) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/wardite/wasi.rb', line 33 def args_get(store, args) arg_offsets_p = args[0].value arg_data_buf_p = args[1].value if !arg_data_buf_p.is_a?(Integer) raise ArgumentError, "invalid type of args: #{args.inspect}" end arg_offsets = [] #: Array[Integer] arg_data_slice = [] #: Array[String] current_offset = arg_data_buf_p @argv.each do |arg| arg_offsets << current_offset arg_data_slice << arg current_offset += arg.size + 1 end arg_data = arg_data_slice.join("\0") + "\0" memory = store.memories[0] memory.data[arg_data_buf_p...(arg_data_buf_p + arg_data.size)] = arg_data arg_offsets.each_with_index do |offset, i| data_begin = arg_offsets_p + i * 4 memory.data[data_begin...(data_begin + 4)] = [offset].pack("I!") end 0 end |
#args_sizes_get(store, args) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/wardite/wasi.rb', line 64 def args_sizes_get(store, args) argc_p = args[0].value arglen_p = args[1].value argc = @argv.length arglen = @argv.map{|arg| arg.size + 1}.sum memory = store.memories[0] memory.data[argc_p...(argc_p+4)] = [argc].pack("I!") memory.data[arglen_p...(arglen_p+4)] = [arglen].pack("I!") 0 end |
#clock_time_get(store, args) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/wardite/wasi.rb', line 125 def clock_time_get(store, args) clock_id = args[0].value # we dont use precision... _precision = args[1].value timebuf64 = args[2].value if clock_id != 0 # - CLOCKID_REALTIME # raise NotImplementedError, "CLOCKID_REALTIME is an only supported id" return -255 end # timestamp in nanoseconds now = Time.now.to_i * 1_000_000 memory = store.memories[0] now_packed = [now].pack("Q!") memory.data[timebuf64...(timebuf64+8)] = now_packed 0 end |
#environ_get(store, args) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/wardite/wasi.rb', line 94 def environ_get(store, args) environ_offsets_p = args[0].value environ_data_buf_p = args[1].value if !environ_data_buf_p.is_a?(Integer) raise ArgumentError, "invalid type of args: #{args.inspect}" end environ_offsets = [] #: Array[Integer] environ_data_slice = [] #: Array[String] current_offset = environ_data_buf_p ENV.each do |k, v| environ_offsets << current_offset environ_data_slice << "#{k}=#{v}" current_offset += "#{k}=#{v}".size + 1 end environ_data = environ_data_slice.join("\0") + "\0" memory = store.memories[0] memory.data[environ_data_buf_p...(environ_data_buf_p + environ_data.size)] = environ_data environ_offsets.each_with_index do |offset, i| data_begin = environ_offsets_p + i * 4 memory.data[data_begin...(data_begin + 4)] = [offset].pack("I!") end 0 end |
#environ_sizes_get(store, args) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/wardite/wasi.rb', line 79 def environ_sizes_get(store, args) envc_p = args[0].value envlen_p = args[1].value envc = ENV.length envlen = ENV.map{|k,v| k.size + v.size + 1}.sum memory = store.memories[0] memory.data[envc_p...(envc_p+4)] = [envc].pack("I!") memory.data[envlen_p...(envlen_p+4)] = [envlen].pack("I!") 0 end |
#fd_fdstat_get(store, args) ⇒ Object
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/wardite/wasi.rb', line 237 def fd_fdstat_get(store, args) fd = args[0].value.to_i fdstat_offset = args[1].value.to_i if fd >= @fd_table.size return Wasi::EBADF end file = @fd_table[fd] fdflags = 0 if file.is_a?(IO) fdflags |= Wasi::FD_APPEND else if (Fcntl::O_APPEND & file.fcntl(Fcntl::F_GETFL, 0)) != 0 fdflags |= Wasi::FD_APPEND end end if (Fcntl::O_NONBLOCK & file.fcntl(Fcntl::F_GETFL, 0)) != 0 fdflags |= Wasi::FD_NONBLOCK end stat = file.stat #: File::Stat ftype = Wasi.to_ftype(stat.ftype) fs_right_base = 0 fs_right_inheriting = 0 case ftype when Wasi::FILETYPE_DIRECTORY fs_right_base = Wasi::RIGHT_DIR_RIGHT_BASE fs_right_inheriting = Wasi::RIGHT_FILE_RIGHT_BASE | Wasi::RIGHT_DIR_RIGHT_BASE when Wasi::FILETYPE_CHARACTER_DEVICE fs_right_base = Wasi::RIGHT_FILE_RIGHT_BASE & \ (~Wasi::RIGHT_FD_SEEK) & (~Wasi::RIGHT_FD_TELL) else fs_right_base = Wasi::RIGHT_FILE_RIGHT_BASE end memory = store.memories[0] binformat = [fdflags, ftype, 0, 0, 0, 0, fs_right_base, fs_right_inheriting] .pack("SSC4QQ") memory.data[fdstat_offset...(fdstat_offset+binformat.size)] = binformat 0 end |
#fd_filestat_get(store, args) ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/wardite/wasi.rb', line 285 def fd_filestat_get(store, args) fd = args[0].value.to_i filestat_offset = args[1].value.to_i if fd >= @fd_table.size return Wasi::EBADF end file = @fd_table[fd] stat = file.stat #: File::Stat memory = store.memories[0] binformat = [stat.dev, stat.ino, Wasi.to_ftype(stat.ftype), stat.nlink, stat.size, stat.atime.to_i, stat.mtime.to_i, stat.ctime.to_i].pack("Q8") memory.data[filestat_offset...(filestat_offset+binformat.size)] = binformat 0 end |
#fd_prestat_get(store, args) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/wardite/wasi.rb', line 146 def fd_prestat_get(store, args) fd = args[0].value.to_i prestat_offset = args[1].value.to_i if fd >= @fd_table.size return Wasi::EBADF end file = @fd_table[fd] if !file.is_a?(File) return Wasi::EBADF end name = file.path memory = store.memories[0] # Zero-value 8-bit tag, and 3-byte zero-value padding memory.data[prestat_offset...(prestat_offset+4)] = [0].pack("I!") memory.data[(prestat_offset+4)...(prestat_offset+8)] = [name.size].pack("I!") 0 end |
#fd_read(store, args) ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/wardite/wasi.rb', line 200 def fd_read(store, args) iargs = args.map do |elm| if elm.is_a?(I32) elm.value else raise Wardite::ArgumentError, "invalid type of args: #{args.inspect}" end end #: Array[Integer] fd, iovs, iovs_len, rp = *iargs if !fd || !iovs || !iovs_len || !rp raise Wardite::ArgumentError, "args too short" end file = self.fd_table[fd] return Wasi::EBADF if !file memory = store.memories[0] nread = 0 iovs_len.times do start = unpack_le_int(memory.data[iovs...(iovs+4)]) iovs += 4 slen = unpack_le_int(memory.data[iovs...(iovs+4)]) iovs += 4 buf = file.read(slen) if !buf return Wasi::EFAULT end memory.data[start...(start+slen)] = buf nread += slen end memory.data[rp...(rp+4)] = [nread].pack("I!") 0 end |
#fd_write(store, args) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/wardite/wasi.rb', line 167 def fd_write(store, args) iargs = args.map do |elm| if elm.is_a?(I32) elm.value else raise Wardite::ArgumentError, "invalid type of args: #{args.inspect}" end end #: Array[Integer] fd, iovs, iovs_len, rp = *iargs if !fd || !iovs || !iovs_len || !rp raise Wardite::ArgumentError, "args too short" end file = self.fd_table[fd] return Wasi::EBADF if !file memory = store.memories[0] nwritten = 0 iovs_len.times do start = unpack_le_int(memory.data[iovs...(iovs+4)]) iovs += 4 slen = unpack_le_int(memory.data[iovs...(iovs+4)]) iovs += 4 # TODO: parallel write? nwritten += file.write(memory.data[start...(start+slen)]) end memory.data[rp...(rp+4)] = [nwritten].pack("I!") 0 end |
#proc_exit(store, args) ⇒ Object
302 303 304 305 |
# File 'lib/wardite/wasi.rb', line 302 def proc_exit(store, args) exit_code = args[0].value exit(exit_code) end |
#random_get(store, args) ⇒ Object
310 311 312 313 314 315 316 317 |
# File 'lib/wardite/wasi.rb', line 310 def random_get(store, args) buf = args[0].value.to_i buflen = args[1].value.to_i randoms = SecureRandom.random_bytes(buflen) #: String memory = store.memories[0] memory.data[buf...(buf+buflen)] = randoms 0 end |