Skip to content

Commit 01365be

Browse files
shriteshandrewrk
authored andcommitted
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
1 parent 77383f9 commit 01365be

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

std/os.zig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,6 +2134,11 @@ pub const ArgIterator = struct {
21342134
inner: InnerType,
21352135

21362136
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+
21372142
return ArgIterator{ .inner = InnerType.init() };
21382143
}
21392144

@@ -2166,6 +2171,34 @@ pub fn args() ArgIterator {
21662171

21672172
/// Caller must call argsFree on result.
21682173
pub 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+
21692202
// TODO refactor to only make 1 allocation.
21702203
var it = args();
21712204
var contents = try Buffer.initSize(allocator, 0);
@@ -2203,6 +2236,16 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
22032236
}
22042237

22052238
pub 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+
22062249
var total_bytes: usize = 0;
22072250
for (args_alloc) |arg| {
22082251
total_bytes += @sizeOf([]u8) + arg.len;

std/os/wasi.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pub use @import("wasi/core.zig");
22

33
// 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.md
4+
// and https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md
55

66
pub const STDIN_FILENO = 0;
77
pub const STDOUT_FILENO = 1;

std/os/wasi/core.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ pub const ciovec_t = extern struct {
1010

1111
pub const SIGABRT: signal_t = 6;
1212

13+
pub extern "wasi_unstable" fn args_get(argv: [*][*]u8, argv_buf: [*]u8) errno_t;
14+
pub extern "wasi_unstable" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
15+
1316
pub extern "wasi_unstable" fn proc_raise(sig: signal_t) errno_t;
1417

1518
pub extern "wasi_unstable" fn proc_exit(rval: exitcode_t) noreturn;

0 commit comments

Comments
 (0)