@@ -2134,6 +2134,11 @@ pub const ArgIterator = struct {
2134
2134
inner : InnerType ,
2135
2135
2136
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
2142
return ArgIterator { .inner = InnerType .init () };
2138
2143
}
2139
2144
@@ -2166,6 +2171,34 @@ pub fn args() ArgIterator {
2166
2171
2167
2172
/// Caller must call argsFree on result.
2168
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
2202
// TODO refactor to only make 1 allocation.
2170
2203
var it = args ();
2171
2204
var contents = try Buffer .initSize (allocator , 0 );
@@ -2203,6 +2236,16 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
2203
2236
}
2204
2237
2205
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
2249
var total_bytes : usize = 0 ;
2207
2250
for (args_alloc ) | arg | {
2208
2251
total_bytes += @sizeOf ([]u8 ) + arg .len ;
0 commit comments