authorgravatar for shritesh@shritesh.comShritesh Bhattarai <shritesh@shritesh.com> 2019-04-29 20:54:30-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-29 21:54:30-04:00
log01365be82fb413061d052c2ecdb761d24d73125d
tree87273e3249f22d624c55cfe0eab7a0ca38912078
parent77383f968dde1e0d5d98865db8f560691d5f2afe

WASI: implement argsAlloc and argsFree (#2364)

* wasi: change URL to canon WASI-core.md * wasi: import args_get and args_sizes_get * wasi: Implement argsAlloc and argsFree * test return value for wasi arg syscalls * wasi: return unexpectedErrorPosix in argsAlloc * wasi: Add TODO for ArgIterator

3 files changed, 47 insertions(+), 1 deletions(-)

std/os.zig+43
...@@ -2134,6 +2134,11 @@ pub const ArgIterator = struct {...@@ -2134,6 +2134,11 @@ pub const ArgIterator = struct {
2134 inner: InnerType,2134 inner: InnerType,
21352135
2136 pub fn init() ArgIterator {2136 pub fn init() ArgIterator {
2137 if (builtin.os == Os.wasi) {
2138 // TODO: Figure out a compatible interface accomodating WASI
2139 @compileError("ArgIterator is not yet supported in WASI. Use argsAlloc and argsFree instead.");
2140 }
2141
2137 return ArgIterator{ .inner = InnerType.init() };2142 return ArgIterator{ .inner = InnerType.init() };
2138 }2143 }
21392144
...@@ -2166,6 +2171,34 @@ pub fn args() ArgIterator {...@@ -2166,6 +2171,34 @@ pub fn args() ArgIterator {
21662171
2167/// Caller must call argsFree on result.2172/// Caller must call argsFree on result.
2168pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {2173pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
2174 if (builtin.os == Os.wasi) {
2175 var count: usize = undefined;
2176 var buf_size: usize = undefined;
2177
2178 const args_sizes_get_ret = os.wasi.args_sizes_get(&count, &buf_size);
2179 if (args_sizes_get_ret != os.wasi.ESUCCESS) {
2180 return unexpectedErrorPosix(args_sizes_get_ret);
2181 }
2182
2183 var argv = try allocator.alloc([*]u8, count);
2184 defer allocator.free(argv);
2185
2186 var argv_buf = try allocator.alloc(u8, buf_size);
2187 const args_get_ret = os.wasi.args_get(argv.ptr, argv_buf.ptr);
2188 if (args_get_ret != os.wasi.ESUCCESS) {
2189 return unexpectedErrorPosix(args_get_ret);
2190 }
2191
2192 var result_slice = try allocator.alloc([]u8, count);
2193
2194 var i: usize = 0;
2195 while (i < count) : (i += 1) {
2196 result_slice[i] = mem.toSlice(u8, argv[i]);
2197 }
2198
2199 return result_slice;
2200 }
2201
2169 // TODO refactor to only make 1 allocation.2202 // TODO refactor to only make 1 allocation.
2170 var it = args();2203 var it = args();
2171 var contents = try Buffer.initSize(allocator, 0);2204 var contents = try Buffer.initSize(allocator, 0);
...@@ -2203,6 +2236,16 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {...@@ -2203,6 +2236,16 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
2203}2236}
22042237
2205pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {2238pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {
2239 if (builtin.os == Os.wasi) {
2240 const last_item = args_alloc[args_alloc.len - 1];
2241 const last_byte_addr = @ptrToInt(last_item.ptr) + last_item.len + 1; // null terminated
2242 const first_item_ptr = args_alloc[0].ptr;
2243 const len = last_byte_addr - @ptrToInt(first_item_ptr);
2244 allocator.free(first_item_ptr[0..len]);
2245
2246 return allocator.free(args_alloc);
2247 }
2248
2206 var total_bytes: usize = 0;2249 var total_bytes: usize = 0;
2207 for (args_alloc) |arg| {2250 for (args_alloc) |arg| {
2208 total_bytes += @sizeOf([]u8) + arg.len;2251 total_bytes += @sizeOf([]u8) + arg.len;
std/os/wasi.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1pub use @import("wasi/core.zig");1pub use @import("wasi/core.zig");
22
3// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h3// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h
4// and https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md4// and https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md
55
6pub const STDIN_FILENO = 0;6pub const STDIN_FILENO = 0;
7pub const STDOUT_FILENO = 1;7pub const STDOUT_FILENO = 1;
std/os/wasi/core.zig+3
...@@ -10,6 +10,9 @@ pub const ciovec_t = extern struct {...@@ -10,6 +10,9 @@ pub const ciovec_t = extern struct {
1010
11pub const SIGABRT: signal_t = 6;11pub const SIGABRT: signal_t = 6;
1212
13pub extern "wasi_unstable" fn args_get(argv: [*][*]u8, argv_buf: [*]u8) errno_t;
14pub extern "wasi_unstable" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
15
13pub extern "wasi_unstable" fn proc_raise(sig: signal_t) errno_t;16pub extern "wasi_unstable" fn proc_raise(sig: signal_t) errno_t;
1417
15pub extern "wasi_unstable" fn proc_exit(rval: exitcode_t) noreturn;18pub extern "wasi_unstable" fn proc_exit(rval: exitcode_t) noreturn;