| ... | @@ -2134,6 +2134,11 @@ pub const ArgIterator = struct { | ... | @@ -2134,6 +2134,11 @@ pub const ArgIterator = struct { |
| 2134 | inner: InnerType, | 2134 | inner: InnerType, |
| 2135 | | 2135 | |
| 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 | } |
| 2139 | | 2144 | |
| ... | @@ -2166,6 +2171,34 @@ pub fn args() ArgIterator { | ... | @@ -2166,6 +2171,34 @@ pub fn args() ArgIterator { |
| 2166 | | 2171 | |
| 2167 | /// Caller must call argsFree on result. | 2172 | /// Caller must call argsFree on result. |
| 2168 | pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 { | 2173 | 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 | |
| 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 | } |
| 2204 | | 2237 | |
| 2205 | pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void { | 2238 | 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 | |
| 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; |