| author | |
| committer | |
| log | 5a8d87f5042b5ab86de7c72df4ce84a314878e40 |
| tree | d9a8e14011994c5ebdf4525ea5c5b647aae91a6e |
| parent | 38658a597bc22697c2038c21bdec9f04c9973eb8 |
| parent | 598170756cd91b6f300921d256baa72141ec3098 |
64 files changed, 1564 insertions(+), 1165 deletions(-)
CMakeLists.txt+1| ... | ... | @@ -440,6 +440,7 @@ set(ZIG_STD_FILES |
| 440 | 440 | "os/windows/error.zig" |
| 441 | 441 | "os/windows/index.zig" |
| 442 | 442 | "os/windows/util.zig" |
| 443 | "os/zen.zig" | |
| 443 | 444 | "rand.zig" |
| 444 | 445 | "sort.zig" |
| 445 | 446 | "special/bootstrap.zig" |
doc/docgen.zig+1-1| ... | ... | @@ -45,7 +45,7 @@ const State = enum { |
| 45 | 45 | fn gen(in: &io.InStream, out: &io.OutStream) { |
| 46 | 46 | var state = State.Start; |
| 47 | 47 | while (true) { |
| 48 | const byte = in.readByte() %% |err| { | |
| 48 | const byte = in.readByte() catch |err| { | |
| 49 | 49 | if (err == error.EndOfStream) { |
| 50 | 50 | return; |
| 51 | 51 | } |
doc/home.html.in+18-18| ... | ... | @@ -75,10 +75,10 @@ |
| 75 | 75 | |
| 76 | 76 | pub fn main() -> %void { |
| 77 | 77 | // If this program is run without stdout attached, exit with an error. |
| 78 | var stdout_file = %return std.io.getStdOut(); | |
| 78 | var stdout_file = try std.io.getStdOut(); | |
| 79 | 79 | // If this program encounters pipe failure when printing to stdout, exit |
| 80 | 80 | // with an error. |
| 81 | %return stdout_file.write("Hello, world!\n"); | |
| 81 | try stdout_file.write("Hello, world!\n"); | |
| 82 | 82 | }</code></pre> |
| 83 | 83 | <p>Build this with:</p> |
| 84 | 84 | <pre>zig build-exe hello.zig</pre> |
| ... | ... | @@ -105,9 +105,9 @@ export fn main(argc: c_int, argv: &amp;&amp;u8) -&gt; c_int { |
| 105 | 105 | var x: T = 0; |
| 106 | 106 | |
| 107 | 107 | for (buf) |c| { |
| 108 | const digit = %return charToDigit(c, radix); | |
| 109 | x = %return mulOverflow(T, x, radix); | |
| 110 | x = %return addOverflow(T, x, digit); | |
| 108 | const digit = try charToDigit(c, radix); | |
| 109 | x = try mulOverflow(T, x, radix); | |
| 110 | x = try addOverflow(T, x, digit); | |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | return x; |
| ... | ... | @@ -142,7 +142,7 @@ pub fn addOverflow(comptime T: type, a: T, b: T) -&gt; %T { |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | fn getNumberWithDefault(s: []u8) -&gt; u32 { |
| 145 | parseUnsigned(u32, s, 10) %% 42 | |
| 145 | parseUnsigned(u32, s, 10) catch 42 | |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | fn getNumberOrCrash(s: []u8) -&gt; u32 { |
| ... | ... | @@ -150,8 +150,8 @@ fn getNumberOrCrash(s: []u8) -&gt; u32 { |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | fn addTwoTogetherOrReturnErr(a_str: []u8, b_str: []u8) -&gt; %u32 { |
| 153 | const a = parseUnsigned(u32, a_str, 10) %% |err| return err; | |
| 154 | const b = parseUnsigned(u32, b_str, 10) %% |err| return err; | |
| 153 | const a = parseUnsigned(u32, a_str, 10) catch |err| return err; | |
| 154 | const b = parseUnsigned(u32, b_str, 10) catch |err| return err; | |
| 155 | 155 | return a + b; |
| 156 | 156 | }</code></pre> |
| 157 | 157 | <h3 id="hashmap">HashMap with Custom Allocator</h3> |
| ... | ... | @@ -234,14 +234,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt |
| 234 | 234 | |
| 235 | 235 | pub fn put(hm: &amp;Self, key: K, value: V) -&gt; %void { |
| 236 | 236 | if (hm.entries.len == 0) { |
| 237 | %return hm.initCapacity(16); | |
| 237 | try hm.initCapacity(16); | |
| 238 | 238 | } |
| 239 | 239 | hm.incrementModificationCount(); |
| 240 | 240 | |
| 241 | 241 | // if we get too full (60%), double the capacity |
| 242 | 242 | if (hm.size * 5 &gt;= hm.entries.len * 3) { |
| 243 | 243 | const old_entries = hm.entries; |
| 244 | %return hm.initCapacity(hm.entries.len * 2); | |
| 244 | try hm.initCapacity(hm.entries.len * 2); | |
| 245 | 245 | // dump all of the old elements into the new table |
| 246 | 246 | for (old_entries) |*old_entry| { |
| 247 | 247 | if (old_entry.used) { |
| ... | ... | @@ -296,7 +296,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | 298 | fn initCapacity(hm: &amp;Self, capacity: usize) -&gt; %void { |
| 299 | hm.entries = %return hm.allocator.alloc(Entry, capacity); | |
| 299 | hm.entries = try hm.allocator.alloc(Entry, capacity); | |
| 300 | 300 | hm.size = 0; |
| 301 | 301 | hm.max_distance_from_start_index = 0; |
| 302 | 302 | for (hm.entries) |*entry| { |
| ... | ... | @@ -420,24 +420,24 @@ pub fn main() -&gt; %void { |
| 420 | 420 | const arg = os.args.at(arg_i); |
| 421 | 421 | if (mem.eql(u8, arg, "-")) { |
| 422 | 422 | catted_anything = true; |
| 423 | %return cat_stream(&amp;io.stdin); | |
| 423 | try cat_stream(&amp;io.stdin); | |
| 424 | 424 | } else if (arg[0] == '-') { |
| 425 | 425 | return usage(exe); |
| 426 | 426 | } else { |
| 427 | var is = io.InStream.open(arg, null) %% |err| { | |
| 427 | var is = io.InStream.open(arg, null) catch |err| { | |
| 428 | 428 | %%io.stderr.printf("Unable to open file: {}\n", @errorName(err)); |
| 429 | 429 | return err; |
| 430 | 430 | }; |
| 431 | 431 | defer is.close(); |
| 432 | 432 | |
| 433 | 433 | catted_anything = true; |
| 434 | %return cat_stream(&amp;is); | |
| 434 | try cat_stream(&amp;is); | |
| 435 | 435 | } |
| 436 | 436 | } |
| 437 | 437 | if (!catted_anything) { |
| 438 | %return cat_stream(&amp;io.stdin); | |
| 438 | try cat_stream(&amp;io.stdin); | |
| 439 | 439 | } |
| 440 | %return io.stdout.flush(); | |
| 440 | try io.stdout.flush(); | |
| 441 | 441 | } |
| 442 | 442 | |
| 443 | 443 | fn usage(exe: []const u8) -&gt; %void { |
| ... | ... | @@ -449,7 +449,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void { |
| 449 | 449 | var buf: [1024 * 4]u8 = undefined; |
| 450 | 450 | |
| 451 | 451 | while (true) { |
| 452 | const bytes_read = is.read(buf[0..]) %% |err| { | |
| 452 | const bytes_read = is.read(buf[0..]) catch |err| { | |
| 453 | 453 | %%io.stderr.printf("Unable to read from stream: {}\n", @errorName(err)); |
| 454 | 454 | return err; |
| 455 | 455 | }; |
| ... | ... | @@ -458,7 +458,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void { |
| 458 | 458 | break; |
| 459 | 459 | } |
| 460 | 460 | |
| 461 | io.stdout.write(buf[0..bytes_read]) %% |err| { | |
| 461 | io.stdout.write(buf[0..bytes_read]) catch |err| { | |
| 462 | 462 | %%io.stderr.printf("Unable to write to stdout: {}\n", @errorName(err)); |
| 463 | 463 | return err; |
| 464 | 464 | }; |
doc/langref.html.in+40-39| ... | ... | @@ -264,15 +264,14 @@ |
| 264 | 264 | please <a href="https://github.com/zig-lang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>. |
| 265 | 265 | </p> |
| 266 | 266 | <h2 id="hello-world">Hello World</h2> |
| 267 | <pre><code class="zig">const io = @import("std").io; | |
| 267 | <pre><code class="zig">const std = @import("std"); | |
| 268 | 268 | |
| 269 | 269 | pub fn main() -&gt; %void { |
| 270 | 270 | // If this program is run without stdout attached, exit with an error. |
| 271 | var stdout_file = %return io.getStdOut(); | |
| 272 | const stdout = &amp;stdout_file.out_stream; | |
| 271 | var stdout_file = try std.io.getStdOut(); | |
| 273 | 272 | // If this program encounters pipe failure when printing to stdout, exit |
| 274 | 273 | // with an error. |
| 275 | %return stdout.print("Hello, world!\n"); | |
| 274 | try stdout_file.write("Hello, world!\n"); | |
| 276 | 275 | }</code></pre> |
| 277 | 276 | <pre><code class="sh">$ zig build-exe hello.zig |
| 278 | 277 | $ ./hello |
| ... | ... | @@ -1212,8 +1211,8 @@ unwrapped == 1234</code></pre> |
| 1212 | 1211 | </td> |
| 1213 | 1212 | </tr> |
| 1214 | 1213 | <tr> |
| 1215 | <td><pre><code class="zig">a %% b | |
| 1216 | a %% |err| b</code></pre></td> | |
| 1214 | <td><pre><code class="zig">a catch b | |
| 1215 | a catch |err| b</code></pre></td> | |
| 1217 | 1216 | <td> |
| 1218 | 1217 | <ul> |
| 1219 | 1218 | <li><a href="#errors">Error Unions</a></li> |
| ... | ... | @@ -1227,7 +1226,7 @@ a %% |err| b</code></pre></td> |
| 1227 | 1226 | </td> |
| 1228 | 1227 | <td> |
| 1229 | 1228 | <pre><code class="zig">const value: %u32 = null; |
| 1230 | const unwrapped = value %% 1234; | |
| 1229 | const unwrapped = value catch 1234; | |
| 1231 | 1230 | unwrapped == 1234</code></pre> |
| 1232 | 1231 | </td> |
| 1233 | 1232 | </tr> |
| ... | ... | @@ -1239,7 +1238,7 @@ unwrapped == 1234</code></pre> |
| 1239 | 1238 | </ul> |
| 1240 | 1239 | </td> |
| 1241 | 1240 | <td>Equivalent to: |
| 1242 | <pre><code class="zig">a %% unreachable</code></pre> | |
| 1241 | <pre><code class="zig">a catch unreachable</code></pre> | |
| 1243 | 1242 | </td> |
| 1244 | 1243 | <td> |
| 1245 | 1244 | <pre><code class="zig">const value: %u32 = 5678; |
| ... | ... | @@ -1483,7 +1482,7 @@ x{} |
| 1483 | 1482 | == != &lt; &gt; &lt;= &gt;= |
| 1484 | 1483 | and |
| 1485 | 1484 | or |
| 1486 | ?? %% | |
| 1485 | ?? catch | |
| 1487 | 1486 | = *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |=</code></pre> |
| 1488 | 1487 | <h2 id="arrays">Arrays</h2> |
| 1489 | 1488 | <pre><code class="zig">const assert = @import("std").debug.assert; |
| ... | ... | @@ -1830,7 +1829,7 @@ Test 1/1 pointer alignment safety...incorrect alignment |
| 1830 | 1829 | return root.main(); |
| 1831 | 1830 | ^ |
| 1832 | 1831 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000216050 in ??? (test) |
| 1833 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | |
| 1832 | callMain(argc, argv, envp) catch std.os.posix.exit(1); | |
| 1834 | 1833 | ^ |
| 1835 | 1834 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000215fa0 in ??? (test) |
| 1836 | 1835 | posixCallMainAndExit() |
| ... | ... | @@ -1886,7 +1885,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x00000000002149e7 in ??? (test) |
| 1886 | 1885 | return root.main(); |
| 1887 | 1886 | ^ |
| 1888 | 1887 | lib/zig/std/special/bootstrap.zig:47:13: 0x00000000002148a0 in ??? (test) |
| 1889 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | |
| 1888 | callMain(argc, argv, envp) catch std.os.posix.exit(1); | |
| 1890 | 1889 | ^ |
| 1891 | 1890 | lib/zig/std/special/bootstrap.zig:34:25: 0x00000000002147f0 in ??? (test) |
| 1892 | 1891 | posixCallMainAndExit() |
| ... | ... | @@ -2966,7 +2965,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x0000000000214947 in ??? (test) |
| 2966 | 2965 | return root.main(); |
| 2967 | 2966 | ^ |
| 2968 | 2967 | lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000214800 in ??? (test) |
| 2969 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | |
| 2968 | callMain(argc, argv, envp) catch std.os.posix.exit(1); | |
| 2970 | 2969 | ^ |
| 2971 | 2970 | lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000214750 in ??? (test) |
| 2972 | 2971 | posixCallMainAndExit() |
| ... | ... | @@ -3020,7 +3019,7 @@ extern fn bar(value: u32);</code></pre> |
| 3020 | 3019 | <pre><code class="zig">pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) -&gt; noreturn; |
| 3021 | 3020 | |
| 3022 | 3021 | fn foo() { |
| 3023 | const value = bar() %% ExitProcess(1); | |
| 3022 | const value = bar() catch ExitProcess(1); | |
| 3024 | 3023 | assert(value == 1234); |
| 3025 | 3024 | } |
| 3026 | 3025 | |
| ... | ... | @@ -3210,7 +3209,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3210 | 3209 | </ul> |
| 3211 | 3210 | <p>If you want to provide a default value, you can use the <code>%%</code> binary operator:</p> |
| 3212 | 3211 | <pre><code class="zig">fn doAThing(str: []u8) { |
| 3213 | const number = parseU64(str, 10) %% 13; | |
| 3212 | const number = parseU64(str, 10) catch 13; | |
| 3214 | 3213 | // ... |
| 3215 | 3214 | }</code></pre> |
| 3216 | 3215 | <p> |
| ... | ... | @@ -3221,18 +3220,18 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3221 | 3220 | <p>Let's say you wanted to return the error if you got one, otherwise continue with the |
| 3222 | 3221 | function logic:</p> |
| 3223 | 3222 | <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void { |
| 3224 | const number = parseU64(str, 10) %% |err| return err; | |
| 3223 | const number = parseU64(str, 10) catch |err| return err; | |
| 3225 | 3224 | // ... |
| 3226 | 3225 | }</code></pre> |
| 3227 | 3226 | <p> |
| 3228 | There is a shortcut for this. The <code>%return</code> expression: | |
| 3227 | There is a shortcut for this. The <code>try</code> expression: | |
| 3229 | 3228 | </p> |
| 3230 | 3229 | <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void { |
| 3231 | const number = %return parseU64(str, 10); | |
| 3230 | const number = try parseU64(str, 10); | |
| 3232 | 3231 | // ... |
| 3233 | 3232 | }</code></pre> |
| 3234 | 3233 | <p> |
| 3235 | <code>%return</code> evaluates an error union expression. If it is an error, it returns | |
| 3234 | <code>try</code> evaluates an error union expression. If it is an error, it returns | |
| 3236 | 3235 | from the current function with the same error. Otherwise, the expression results in |
| 3237 | 3236 | the unwrapped value. |
| 3238 | 3237 | </p> |
| ... | ... | @@ -3240,7 +3239,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3240 | 3239 | Maybe you know with complete certainty that an expression will never be an error. |
| 3241 | 3240 | In this case you can do this: |
| 3242 | 3241 | </p> |
| 3243 | <pre><code class="zig">const number = parseU64("1234", 10) %% unreachable;</code></pre> | |
| 3242 | <pre><code class="zig">const number = parseU64("1234", 10) catch unreachable;</code></pre> | |
| 3244 | 3243 | <p> |
| 3245 | 3244 | Here we know for sure that "1234" will parse successfully. So we put the |
| 3246 | 3245 | <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates |
| ... | ... | @@ -3251,7 +3250,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3251 | 3250 | <p>Again there is a syntactic shortcut for this:</p> |
| 3252 | 3251 | <pre><code class="zig">const number = %%parseU64("1234", 10);</code></pre> |
| 3253 | 3252 | <p> |
| 3254 | The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression %% unreachable</code>. It unwraps an error union type, | |
| 3253 | The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression catch unreachable</code>. It unwraps an error union type, | |
| 3255 | 3254 | and panics in debug mode if the value was an error. |
| 3256 | 3255 | </p> |
| 3257 | 3256 | <p> |
| ... | ... | @@ -3279,7 +3278,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 { |
| 3279 | 3278 | Example: |
| 3280 | 3279 | </p> |
| 3281 | 3280 | <pre><code class="zig">fn createFoo(param: i32) -&gt; %Foo { |
| 3282 | const foo = %return tryToAllocateFoo(); | |
| 3281 | const foo = try tryToAllocateFoo(); | |
| 3283 | 3282 | // now we have allocated foo. we need to free it if the function fails. |
| 3284 | 3283 | // but we want to return it if the function succeeds. |
| 3285 | 3284 | %defer deallocateFoo(foo); |
| ... | ... | @@ -3929,11 +3928,11 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3929 | 3928 | switch (state) { |
| 3930 | 3929 | State.Start =&gt; switch (c) { |
| 3931 | 3930 | '{' =&gt; { |
| 3932 | if (start_index &lt; i) %return self.write(format[start_index...i]); | |
| 3931 | if (start_index &lt; i) try self.write(format[start_index...i]); | |
| 3933 | 3932 | state = State.OpenBrace; |
| 3934 | 3933 | }, |
| 3935 | 3934 | '}' =&gt; { |
| 3936 | if (start_index &lt; i) %return self.write(format[start_index...i]); | |
| 3935 | if (start_index &lt; i) try self.write(format[start_index...i]); | |
| 3937 | 3936 | state = State.CloseBrace; |
| 3938 | 3937 | }, |
| 3939 | 3938 | else =&gt; {}, |
| ... | ... | @@ -3944,7 +3943,7 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3944 | 3943 | start_index = i; |
| 3945 | 3944 | }, |
| 3946 | 3945 | '}' =&gt; { |
| 3947 | %return self.printValue(args[next_arg]); | |
| 3946 | try self.printValue(args[next_arg]); | |
| 3948 | 3947 | next_arg += 1; |
| 3949 | 3948 | state = State.Start; |
| 3950 | 3949 | start_index = i + 1; |
| ... | ... | @@ -3969,9 +3968,9 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3969 | 3968 | } |
| 3970 | 3969 | } |
| 3971 | 3970 | if (start_index &lt; format.len) { |
| 3972 | %return self.write(format[start_index...format.len]); | |
| 3971 | try self.write(format[start_index...format.len]); | |
| 3973 | 3972 | } |
| 3974 | %return self.flush(); | |
| 3973 | try self.flush(); | |
| 3975 | 3974 | }</code></pre> |
| 3976 | 3975 | <p> |
| 3977 | 3976 | This is a proof of concept implementation; the actual function in the standard library has more |
| ... | ... | @@ -3985,12 +3984,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt |
| 3985 | 3984 | and emits a function that actually looks like this: |
| 3986 | 3985 | </p> |
| 3987 | 3986 | <pre><code class="zig">pub fn printf(self: &amp;OutStream, arg0: i32, arg1: []const u8) -&gt; %void { |
| 3988 | %return self.write("here is a string: '"); | |
| 3989 | %return self.printValue(arg0); | |
| 3990 | %return self.write("' here is a number: "); | |
| 3991 | %return self.printValue(arg1); | |
| 3992 | %return self.write("\n"); | |
| 3993 | %return self.flush(); | |
| 3987 | try self.write("here is a string: '"); | |
| 3988 | try self.printValue(arg0); | |
| 3989 | try self.write("' here is a number: "); | |
| 3990 | try self.printValue(arg1); | |
| 3991 | try self.write("\n"); | |
| 3992 | try self.flush(); | |
| 3994 | 3993 | }</code></pre> |
| 3995 | 3994 | <p> |
| 3996 | 3995 | <code>printValue</code> is a function that takes a parameter of any type, and does different things depending |
| ... | ... | @@ -4985,7 +4984,7 @@ Test 1/1 safety check...reached unreachable code |
| 4985 | 4984 | return root.main(); |
| 4986 | 4985 | ^ |
| 4987 | 4986 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:37:13: 0x00000000002148d0 in ??? (test) |
| 4988 | callMain(argc, argv, envp) %% exit(1); | |
| 4987 | callMain(argc, argv, envp) catch exit(1); | |
| 4989 | 4988 | ^ |
| 4990 | 4989 | /home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:30:20: 0x0000000000214820 in ??? (test) |
| 4991 | 4990 | callMainAndExit() |
| ... | ... | @@ -5892,7 +5891,7 @@ TypeExpr = PrefixOpExpression | "var" |
| 5892 | 5891 | |
| 5893 | 5892 | BlockOrExpression = Block | Expression |
| 5894 | 5893 | |
| 5895 | Expression = ReturnExpression | BreakExpression | AssignmentExpression | |
| 5894 | Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression | |
| 5896 | 5895 | |
| 5897 | 5896 | AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")" |
| 5898 | 5897 | |
| ... | ... | @@ -5910,13 +5909,13 @@ UnwrapExpression = BoolOrExpression (UnwrapNullable | UnwrapError) | BoolOrExpre |
| 5910 | 5909 | |
| 5911 | 5910 | UnwrapNullable = "??" Expression |
| 5912 | 5911 | |
| 5913 | UnwrapError = "%%" option("|" Symbol "|") Expression | |
| 5912 | UnwrapError = "catch" option("|" Symbol "|") Expression | |
| 5914 | 5913 | |
| 5915 | 5914 | AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression |
| 5916 | 5915 | |
| 5917 | 5916 | AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&lt;&lt;=" | "&gt;&gt;=" | "&amp;=" | "^=" | "|=" | "*%=" | "+%=" | "-%=" |
| 5918 | 5917 | |
| 5919 | BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | |
| 5918 | BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body) | |
| 5920 | 5919 | |
| 5921 | 5920 | CompTimeExpression(body) = "comptime" body |
| 5922 | 5921 | |
| ... | ... | @@ -5930,7 +5929,9 @@ ForExpression(body) = option(Symbol ":") option("inline") "for" "(" Expression " |
| 5930 | 5929 | |
| 5931 | 5930 | BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression |
| 5932 | 5931 | |
| 5933 | ReturnExpression = option("%") "return" option(Expression) | |
| 5932 | ReturnExpression = "return" option(Expression) | |
| 5933 | ||
| 5934 | TryExpression = "try" Expression | |
| 5934 | 5935 | |
| 5935 | 5936 | BreakExpression = "break" option(":" Symbol) option(Expression) |
| 5936 | 5937 | |
| ... | ... | @@ -5938,7 +5939,7 @@ Defer(body) = option("%") "defer" body |
| 5938 | 5939 | |
| 5939 | 5940 | IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body)) |
| 5940 | 5941 | |
| 5941 | TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body) | |
| 5942 | IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body) | |
| 5942 | 5943 | |
| 5943 | 5944 | TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body)) |
| 5944 | 5945 | |
| ... | ... | @@ -5988,7 +5989,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",") |
| 5988 | 5989 | |
| 5989 | 5990 | StructLiteralField = "." Symbol "=" Expression |
| 5990 | 5991 | |
| 5991 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | |
| 5992 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try" | |
| 5992 | 5993 | |
| 5993 | 5994 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol)) |
| 5994 | 5995 |
example/cat/main.zig+12-12| ... | ... | @@ -7,32 +7,32 @@ const allocator = std.debug.global_allocator; |
| 7 | 7 | |
| 8 | 8 | pub fn main() -> %void { |
| 9 | 9 | var args_it = os.args(); |
| 10 | const exe = %return unwrapArg(??args_it.next(allocator)); | |
| 10 | const exe = try unwrapArg(??args_it.next(allocator)); | |
| 11 | 11 | var catted_anything = false; |
| 12 | var stdout_file = %return io.getStdOut(); | |
| 12 | var stdout_file = try io.getStdOut(); | |
| 13 | 13 | |
| 14 | 14 | while (args_it.next(allocator)) |arg_or_err| { |
| 15 | const arg = %return unwrapArg(arg_or_err); | |
| 15 | const arg = try unwrapArg(arg_or_err); | |
| 16 | 16 | if (mem.eql(u8, arg, "-")) { |
| 17 | 17 | catted_anything = true; |
| 18 | var stdin_file = %return io.getStdIn(); | |
| 19 | %return cat_file(&stdout_file, &stdin_file); | |
| 18 | var stdin_file = try io.getStdIn(); | |
| 19 | try cat_file(&stdout_file, &stdin_file); | |
| 20 | 20 | } else if (arg[0] == '-') { |
| 21 | 21 | return usage(exe); |
| 22 | 22 | } else { |
| 23 | var file = io.File.openRead(arg, null) %% |err| { | |
| 23 | var file = io.File.openRead(arg, null) catch |err| { | |
| 24 | 24 | warn("Unable to open file: {}\n", @errorName(err)); |
| 25 | 25 | return err; |
| 26 | 26 | }; |
| 27 | 27 | defer file.close(); |
| 28 | 28 | |
| 29 | 29 | catted_anything = true; |
| 30 | %return cat_file(&stdout_file, &file); | |
| 30 | try cat_file(&stdout_file, &file); | |
| 31 | 31 | } |
| 32 | 32 | } |
| 33 | 33 | if (!catted_anything) { |
| 34 | var stdin_file = %return io.getStdIn(); | |
| 35 | %return cat_file(&stdout_file, &stdin_file); | |
| 34 | var stdin_file = try io.getStdIn(); | |
| 35 | try cat_file(&stdout_file, &stdin_file); | |
| 36 | 36 | } |
| 37 | 37 | } |
| 38 | 38 | |
| ... | ... | @@ -45,7 +45,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { |
| 45 | 45 | var buf: [1024 * 4]u8 = undefined; |
| 46 | 46 | |
| 47 | 47 | while (true) { |
| 48 | const bytes_read = file.read(buf[0..]) %% |err| { | |
| 48 | const bytes_read = file.read(buf[0..]) catch |err| { | |
| 49 | 49 | warn("Unable to read from stream: {}\n", @errorName(err)); |
| 50 | 50 | return err; |
| 51 | 51 | }; |
| ... | ... | @@ -54,7 +54,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { |
| 54 | 54 | break; |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | stdout.write(buf[0..bytes_read]) %% |err| { | |
| 57 | stdout.write(buf[0..bytes_read]) catch |err| { | |
| 58 | 58 | warn("Unable to write to stdout: {}\n", @errorName(err)); |
| 59 | 59 | return err; |
| 60 | 60 | }; |
| ... | ... | @@ -62,7 +62,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void { |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | fn unwrapArg(arg: %[]u8) -> %[]u8 { |
| 65 | return arg %% |err| { | |
| 65 | return arg catch |err| { | |
| 66 | 66 | warn("Unable to parse command line: {}\n", err); |
| 67 | 67 | return err; |
| 68 | 68 | }; |
example/guess_number/main.zig+11-11| ... | ... | @@ -6,13 +6,13 @@ const Rand = std.rand.Rand; |
| 6 | 6 | const os = std.os; |
| 7 | 7 | |
| 8 | 8 | pub fn main() -> %void { |
| 9 | var stdout_file = %return io.getStdOut(); | |
| 9 | var stdout_file = try io.getStdOut(); | |
| 10 | 10 | var stdout_file_stream = io.FileOutStream.init(&stdout_file); |
| 11 | 11 | const stdout = &stdout_file_stream.stream; |
| 12 | 12 | |
| 13 | var stdin_file = %return io.getStdIn(); | |
| 13 | var stdin_file = try io.getStdIn(); | |
| 14 | 14 | |
| 15 | %return stdout.print("Welcome to the Guess Number Game in Zig.\n"); | |
| 15 | try stdout.print("Welcome to the Guess Number Game in Zig.\n"); | |
| 16 | 16 | |
| 17 | 17 | var seed_bytes: [@sizeOf(usize)]u8 = undefined; |
| 18 | 18 | %%os.getRandomBytes(seed_bytes[0..]); |
| ... | ... | @@ -22,24 +22,24 @@ pub fn main() -> %void { |
| 22 | 22 | const answer = rand.range(u8, 0, 100) + 1; |
| 23 | 23 | |
| 24 | 24 | while (true) { |
| 25 | %return stdout.print("\nGuess a number between 1 and 100: "); | |
| 25 | try stdout.print("\nGuess a number between 1 and 100: "); | |
| 26 | 26 | var line_buf : [20]u8 = undefined; |
| 27 | 27 | |
| 28 | const line_len = stdin_file.read(line_buf[0..]) %% |err| { | |
| 29 | %return stdout.print("Unable to read from stdin: {}\n", @errorName(err)); | |
| 28 | const line_len = stdin_file.read(line_buf[0..]) catch |err| { | |
| 29 | try stdout.print("Unable to read from stdin: {}\n", @errorName(err)); | |
| 30 | 30 | return err; |
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | const guess = fmt.parseUnsigned(u8, line_buf[0..line_len - 1], 10) %% { | |
| 34 | %return stdout.print("Invalid number.\n"); | |
| 33 | const guess = fmt.parseUnsigned(u8, line_buf[0..line_len - 1], 10) catch { | |
| 34 | try stdout.print("Invalid number.\n"); | |
| 35 | 35 | continue; |
| 36 | 36 | }; |
| 37 | 37 | if (guess > answer) { |
| 38 | %return stdout.print("Guess lower.\n"); | |
| 38 | try stdout.print("Guess lower.\n"); | |
| 39 | 39 | } else if (guess < answer) { |
| 40 | %return stdout.print("Guess higher.\n"); | |
| 40 | try stdout.print("Guess higher.\n"); | |
| 41 | 41 | } else { |
| 42 | %return stdout.print("You win!\n"); | |
| 42 | try stdout.print("You win!\n"); | |
| 43 | 43 | return; |
| 44 | 44 | } |
| 45 | 45 | } |
example/hello_world/hello.zig+2-2| ... | ... | @@ -2,8 +2,8 @@ const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn main() -> %void { |
| 4 | 4 | // If this program is run without stdout attached, exit with an error. |
| 5 | var stdout_file = %return std.io.getStdOut(); | |
| 5 | var stdout_file = try std.io.getStdOut(); | |
| 6 | 6 | // If this program encounters pipe failure when printing to stdout, exit |
| 7 | 7 | // with an error. |
| 8 | %return stdout_file.write("Hello, world!\n"); | |
| 8 | try stdout_file.write("Hello, world!\n"); | |
| 9 | 9 | } |
src-self-hosted/main.zig+42-42| ... | ... | @@ -21,7 +21,7 @@ error ZigInstallationNotFound; |
| 21 | 21 | const default_zig_cache_name = "zig-cache"; |
| 22 | 22 | |
| 23 | 23 | pub fn main() -> %void { |
| 24 | main2() %% |err| { | |
| 24 | main2() catch |err| { | |
| 25 | 25 | if (err != error.InvalidCommandLineArguments) { |
| 26 | 26 | warn("{}\n", @errorName(err)); |
| 27 | 27 | } |
| ... | ... | @@ -40,18 +40,18 @@ const Cmd = enum { |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | 42 | fn badArgs(comptime format: []const u8, args: ...) -> error { |
| 43 | var stderr = %return io.getStdErr(); | |
| 43 | var stderr = try io.getStdErr(); | |
| 44 | 44 | var stderr_stream_adapter = io.FileOutStream.init(&stderr); |
| 45 | 45 | const stderr_stream = &stderr_stream_adapter.stream; |
| 46 | %return stderr_stream.print(format ++ "\n\n", args); | |
| 47 | %return printUsage(&stderr_stream_adapter.stream); | |
| 46 | try stderr_stream.print(format ++ "\n\n", args); | |
| 47 | try printUsage(&stderr_stream_adapter.stream); | |
| 48 | 48 | return error.InvalidCommandLineArguments; |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | pub fn main2() -> %void { |
| 52 | 52 | const allocator = std.heap.c_allocator; |
| 53 | 53 | |
| 54 | const args = %return os.argsAlloc(allocator); | |
| 54 | const args = try os.argsAlloc(allocator); | |
| 55 | 55 | defer os.argsFree(allocator, args); |
| 56 | 56 | |
| 57 | 57 | var cmd = Cmd.None; |
| ... | ... | @@ -167,7 +167,7 @@ pub fn main2() -> %void { |
| 167 | 167 | @panic("TODO --test-cmd-bin"); |
| 168 | 168 | } else if (arg[1] == 'L' and arg.len > 2) { |
| 169 | 169 | // alias for --library-path |
| 170 | %return lib_dirs.append(arg[1..]); | |
| 170 | try lib_dirs.append(arg[1..]); | |
| 171 | 171 | } else if (mem.eql(u8, arg, "--pkg-begin")) { |
| 172 | 172 | @panic("TODO --pkg-begin"); |
| 173 | 173 | } else if (mem.eql(u8, arg, "--pkg-end")) { |
| ... | ... | @@ -217,24 +217,24 @@ pub fn main2() -> %void { |
| 217 | 217 | } else if (mem.eql(u8, arg, "--dynamic-linker")) { |
| 218 | 218 | dynamic_linker_arg = args[arg_i]; |
| 219 | 219 | } else if (mem.eql(u8, arg, "-isystem")) { |
| 220 | %return clang_argv.append("-isystem"); | |
| 221 | %return clang_argv.append(args[arg_i]); | |
| 220 | try clang_argv.append("-isystem"); | |
| 221 | try clang_argv.append(args[arg_i]); | |
| 222 | 222 | } else if (mem.eql(u8, arg, "-dirafter")) { |
| 223 | %return clang_argv.append("-dirafter"); | |
| 224 | %return clang_argv.append(args[arg_i]); | |
| 223 | try clang_argv.append("-dirafter"); | |
| 224 | try clang_argv.append(args[arg_i]); | |
| 225 | 225 | } else if (mem.eql(u8, arg, "-mllvm")) { |
| 226 | %return clang_argv.append("-mllvm"); | |
| 227 | %return clang_argv.append(args[arg_i]); | |
| 226 | try clang_argv.append("-mllvm"); | |
| 227 | try clang_argv.append(args[arg_i]); | |
| 228 | 228 | |
| 229 | %return llvm_argv.append(args[arg_i]); | |
| 229 | try llvm_argv.append(args[arg_i]); | |
| 230 | 230 | } else if (mem.eql(u8, arg, "--library-path") or mem.eql(u8, arg, "-L")) { |
| 231 | %return lib_dirs.append(args[arg_i]); | |
| 231 | try lib_dirs.append(args[arg_i]); | |
| 232 | 232 | } else if (mem.eql(u8, arg, "--library")) { |
| 233 | %return link_libs.append(args[arg_i]); | |
| 233 | try link_libs.append(args[arg_i]); | |
| 234 | 234 | } else if (mem.eql(u8, arg, "--object")) { |
| 235 | %return objects.append(args[arg_i]); | |
| 235 | try objects.append(args[arg_i]); | |
| 236 | 236 | } else if (mem.eql(u8, arg, "--assembly")) { |
| 237 | %return asm_files.append(args[arg_i]); | |
| 237 | try asm_files.append(args[arg_i]); | |
| 238 | 238 | } else if (mem.eql(u8, arg, "--cache-dir")) { |
| 239 | 239 | cache_dir_arg = args[arg_i]; |
| 240 | 240 | } else if (mem.eql(u8, arg, "--target-arch")) { |
| ... | ... | @@ -248,21 +248,21 @@ pub fn main2() -> %void { |
| 248 | 248 | } else if (mem.eql(u8, arg, "-mios-version-min")) { |
| 249 | 249 | mios_version_min = args[arg_i]; |
| 250 | 250 | } else if (mem.eql(u8, arg, "-framework")) { |
| 251 | %return frameworks.append(args[arg_i]); | |
| 251 | try frameworks.append(args[arg_i]); | |
| 252 | 252 | } else if (mem.eql(u8, arg, "--linker-script")) { |
| 253 | 253 | linker_script_arg = args[arg_i]; |
| 254 | 254 | } else if (mem.eql(u8, arg, "-rpath")) { |
| 255 | %return rpath_list.append(args[arg_i]); | |
| 255 | try rpath_list.append(args[arg_i]); | |
| 256 | 256 | } else if (mem.eql(u8, arg, "--test-filter")) { |
| 257 | %return test_filters.append(args[arg_i]); | |
| 257 | try test_filters.append(args[arg_i]); | |
| 258 | 258 | } else if (mem.eql(u8, arg, "--test-name-prefix")) { |
| 259 | 259 | test_name_prefix_arg = args[arg_i]; |
| 260 | 260 | } else if (mem.eql(u8, arg, "--ver-major")) { |
| 261 | ver_major = %return std.fmt.parseUnsigned(u32, args[arg_i], 10); | |
| 261 | ver_major = try std.fmt.parseUnsigned(u32, args[arg_i], 10); | |
| 262 | 262 | } else if (mem.eql(u8, arg, "--ver-minor")) { |
| 263 | ver_minor = %return std.fmt.parseUnsigned(u32, args[arg_i], 10); | |
| 263 | ver_minor = try std.fmt.parseUnsigned(u32, args[arg_i], 10); | |
| 264 | 264 | } else if (mem.eql(u8, arg, "--ver-patch")) { |
| 265 | ver_patch = %return std.fmt.parseUnsigned(u32, args[arg_i], 10); | |
| 265 | ver_patch = try std.fmt.parseUnsigned(u32, args[arg_i], 10); | |
| 266 | 266 | } else if (mem.eql(u8, arg, "--test-cmd")) { |
| 267 | 267 | @panic("TODO --test-cmd"); |
| 268 | 268 | } else { |
| ... | ... | @@ -367,13 +367,13 @@ pub fn main2() -> %void { |
| 367 | 367 | const zig_root_source_file = if (cmd == Cmd.TranslateC) null else in_file_arg; |
| 368 | 368 | |
| 369 | 369 | const chosen_cache_dir = cache_dir_arg ?? default_zig_cache_name; |
| 370 | const full_cache_dir = %return os.path.resolve(allocator, ".", chosen_cache_dir); | |
| 370 | const full_cache_dir = try os.path.resolve(allocator, ".", chosen_cache_dir); | |
| 371 | 371 | defer allocator.free(full_cache_dir); |
| 372 | 372 | |
| 373 | const zig_lib_dir = %return resolveZigLibDir(allocator, zig_install_prefix); | |
| 373 | const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix); | |
| 374 | 374 | %defer allocator.free(zig_lib_dir); |
| 375 | 375 | |
| 376 | const module = %return Module.create(allocator, root_name, zig_root_source_file, | |
| 376 | const module = try Module.create(allocator, root_name, zig_root_source_file, | |
| 377 | 377 | Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir); |
| 378 | 378 | defer module.destroy(); |
| 379 | 379 | |
| ... | ... | @@ -424,7 +424,7 @@ pub fn main2() -> %void { |
| 424 | 424 | module.rpath_list = rpath_list.toSliceConst(); |
| 425 | 425 | |
| 426 | 426 | for (link_libs.toSliceConst()) |name| { |
| 427 | _ = %return module.addLinkLib(name, true); | |
| 427 | _ = try module.addLinkLib(name, true); | |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | 430 | module.windows_subsystem_windows = mwindows; |
| ... | ... | @@ -455,8 +455,8 @@ pub fn main2() -> %void { |
| 455 | 455 | module.link_objects = objects.toSliceConst(); |
| 456 | 456 | module.assembly_files = asm_files.toSliceConst(); |
| 457 | 457 | |
| 458 | %return module.build(); | |
| 459 | %return module.link(out_file); | |
| 458 | try module.build(); | |
| 459 | try module.link(out_file); | |
| 460 | 460 | }, |
| 461 | 461 | Cmd.TranslateC => @panic("TODO translate-c"), |
| 462 | 462 | Cmd.Test => @panic("TODO test cmd"), |
| ... | ... | @@ -464,16 +464,16 @@ pub fn main2() -> %void { |
| 464 | 464 | } |
| 465 | 465 | }, |
| 466 | 466 | Cmd.Version => { |
| 467 | var stdout_file = %return io.getStdErr(); | |
| 468 | %return stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING)); | |
| 469 | %return stdout_file.write("\n"); | |
| 467 | var stdout_file = try io.getStdErr(); | |
| 468 | try stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING)); | |
| 469 | try stdout_file.write("\n"); | |
| 470 | 470 | }, |
| 471 | 471 | Cmd.Targets => @panic("TODO zig targets"), |
| 472 | 472 | } |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | 475 | fn printUsage(stream: &io.OutStream) -> %void { |
| 476 | %return stream.write( | |
| 476 | try stream.write( | |
| 477 | 477 | \\Usage: zig [command] [options] |
| 478 | 478 | \\ |
| 479 | 479 | \\Commands: |
| ... | ... | @@ -549,8 +549,8 @@ fn printUsage(stream: &io.OutStream) -> %void { |
| 549 | 549 | } |
| 550 | 550 | |
| 551 | 551 | fn printZen() -> %void { |
| 552 | var stdout_file = %return io.getStdErr(); | |
| 553 | %return stdout_file.write( | |
| 552 | var stdout_file = try io.getStdErr(); | |
| 553 | try stdout_file.write( | |
| 554 | 554 | \\ |
| 555 | 555 | \\ * Communicate intent precisely. |
| 556 | 556 | \\ * Edge cases matter. |
| ... | ... | @@ -571,12 +571,12 @@ fn printZen() -> %void { |
| 571 | 571 | /// Caller must free result |
| 572 | 572 | fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) -> %[]u8 { |
| 573 | 573 | if (zig_install_prefix_arg) |zig_install_prefix| { |
| 574 | return testZigInstallPrefix(allocator, zig_install_prefix) %% |err| { | |
| 574 | return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| { | |
| 575 | 575 | warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err)); |
| 576 | 576 | return error.ZigInstallationNotFound; |
| 577 | 577 | }; |
| 578 | 578 | } else { |
| 579 | return findZigLibDir(allocator) %% |err| { | |
| 579 | return findZigLibDir(allocator) catch |err| { | |
| 580 | 580 | warn("Unable to find zig lib directory: {}.\nReinstall Zig or use --zig-install-prefix.\n", |
| 581 | 581 | @errorName(err)); |
| 582 | 582 | return error.ZigLibDirNotFound; |
| ... | ... | @@ -586,13 +586,13 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const |
| 586 | 586 | |
| 587 | 587 | /// Caller must free result |
| 588 | 588 | fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 { |
| 589 | const test_zig_dir = %return os.path.join(allocator, test_path, "lib", "zig"); | |
| 589 | const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig"); | |
| 590 | 590 | %defer allocator.free(test_zig_dir); |
| 591 | 591 | |
| 592 | const test_index_file = %return os.path.join(allocator, test_zig_dir, "std", "index.zig"); | |
| 592 | const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig"); | |
| 593 | 593 | defer allocator.free(test_index_file); |
| 594 | 594 | |
| 595 | var file = %return io.File.openRead(test_index_file, allocator); | |
| 595 | var file = try io.File.openRead(test_index_file, allocator); | |
| 596 | 596 | file.close(); |
| 597 | 597 | |
| 598 | 598 | return test_zig_dir; |
| ... | ... | @@ -600,7 +600,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[] |
| 600 | 600 | |
| 601 | 601 | /// Caller must free result |
| 602 | 602 | fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 { |
| 603 | const self_exe_path = %return os.selfExeDirPath(allocator); | |
| 603 | const self_exe_path = try os.selfExeDirPath(allocator); | |
| 604 | 604 | defer allocator.free(self_exe_path); |
| 605 | 605 | |
| 606 | 606 | var cur_path: []const u8 = self_exe_path; |
| ... | ... | @@ -611,7 +611,7 @@ fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 { |
| 611 | 611 | break; |
| 612 | 612 | } |
| 613 | 613 | |
| 614 | return testZigInstallPrefix(allocator, test_dir) %% |err| { | |
| 614 | return testZigInstallPrefix(allocator, test_dir) catch |err| { | |
| 615 | 615 | cur_path = test_dir; |
| 616 | 616 | continue; |
| 617 | 617 | }; |
src-self-hosted/module.zig+15-15| ... | ... | @@ -112,7 +112,7 @@ pub const Module = struct { |
| 112 | 112 | pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, |
| 113 | 113 | kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) -> %&Module |
| 114 | 114 | { |
| 115 | var name_buffer = %return Buffer.init(allocator, name); | |
| 115 | var name_buffer = try Buffer.init(allocator, name); | |
| 116 | 116 | %defer name_buffer.deinit(); |
| 117 | 117 | |
| 118 | 118 | const context = c.LLVMContextCreate() ?? return error.OutOfMemory; |
| ... | ... | @@ -124,7 +124,7 @@ pub const Module = struct { |
| 124 | 124 | const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory; |
| 125 | 125 | %defer c.LLVMDisposeBuilder(builder); |
| 126 | 126 | |
| 127 | const module_ptr = %return allocator.create(Module); | |
| 127 | const module_ptr = try allocator.create(Module); | |
| 128 | 128 | %defer allocator.destroy(module_ptr); |
| 129 | 129 | |
| 130 | 130 | *module_ptr = Module { |
| ... | ... | @@ -200,21 +200,21 @@ pub const Module = struct { |
| 200 | 200 | |
| 201 | 201 | pub fn build(self: &Module) -> %void { |
| 202 | 202 | if (self.llvm_argv.len != 0) { |
| 203 | var c_compatible_args = %return std.cstr.NullTerminated2DArray.fromSlices(self.allocator, | |
| 203 | var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator, | |
| 204 | 204 | [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, }); |
| 205 | 205 | defer c_compatible_args.deinit(); |
| 206 | 206 | c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr); |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path"); |
| 210 | const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| { | |
| 211 | %return printError("unable to get real path '{}': {}", root_src_path, err); | |
| 210 | const root_src_real_path = os.path.real(self.allocator, root_src_path) catch |err| { | |
| 211 | try printError("unable to get real path '{}': {}", root_src_path, err); | |
| 212 | 212 | return err; |
| 213 | 213 | }; |
| 214 | 214 | %defer self.allocator.free(root_src_real_path); |
| 215 | 215 | |
| 216 | const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) %% |err| { | |
| 217 | %return printError("unable to open '{}': {}", root_src_real_path, err); | |
| 216 | const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| { | |
| 217 | try printError("unable to open '{}': {}", root_src_real_path, err); | |
| 218 | 218 | return err; |
| 219 | 219 | }; |
| 220 | 220 | %defer self.allocator.free(source_code); |
| ... | ... | @@ -244,16 +244,16 @@ pub const Module = struct { |
| 244 | 244 | var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path); |
| 245 | 245 | defer parser.deinit(); |
| 246 | 246 | |
| 247 | const root_node = %return parser.parse(); | |
| 247 | const root_node = try parser.parse(); | |
| 248 | 248 | defer parser.freeAst(root_node); |
| 249 | 249 | |
| 250 | var stderr_file = %return std.io.getStdErr(); | |
| 250 | var stderr_file = try std.io.getStdErr(); | |
| 251 | 251 | var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file); |
| 252 | 252 | const out_stream = &stderr_file_out_stream.stream; |
| 253 | %return parser.renderAst(out_stream, root_node); | |
| 253 | try parser.renderAst(out_stream, root_node); | |
| 254 | 254 | |
| 255 | 255 | warn("====fmt:====\n"); |
| 256 | %return parser.renderSource(out_stream, root_node); | |
| 256 | try parser.renderSource(out_stream, root_node); | |
| 257 | 257 | |
| 258 | 258 | warn("====ir:====\n"); |
| 259 | 259 | warn("TODO\n\n"); |
| ... | ... | @@ -282,14 +282,14 @@ pub const Module = struct { |
| 282 | 282 | } |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | const link_lib = %return self.allocator.create(LinkLib); | |
| 285 | const link_lib = try self.allocator.create(LinkLib); | |
| 286 | 286 | *link_lib = LinkLib { |
| 287 | 287 | .name = name, |
| 288 | 288 | .path = null, |
| 289 | 289 | .provided_explicitly = provided_explicitly, |
| 290 | 290 | .symbols = ArrayList([]u8).init(self.allocator), |
| 291 | 291 | }; |
| 292 | %return self.link_libs_list.append(link_lib); | |
| 292 | try self.link_libs_list.append(link_lib); | |
| 293 | 293 | if (is_libc) { |
| 294 | 294 | self.libc_link_lib = link_lib; |
| 295 | 295 | } |
| ... | ... | @@ -298,8 +298,8 @@ pub const Module = struct { |
| 298 | 298 | }; |
| 299 | 299 | |
| 300 | 300 | fn printError(comptime format: []const u8, args: ...) -> %void { |
| 301 | var stderr_file = %return std.io.getStdErr(); | |
| 301 | var stderr_file = try std.io.getStdErr(); | |
| 302 | 302 | var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file); |
| 303 | 303 | const out_stream = &stderr_file_out_stream.stream; |
| 304 | %return out_stream.print(format, args); | |
| 304 | try out_stream.print(format, args); | |
| 305 | 305 | } |
src-self-hosted/parser.zig+175-175| ... | ... | @@ -58,7 +58,7 @@ pub const Parser = struct { |
| 58 | 58 | switch (*self) { |
| 59 | 59 | DestPtr.Field => |ptr| *ptr = value, |
| 60 | 60 | DestPtr.NullableField => |ptr| *ptr = value, |
| 61 | DestPtr.List => |list| %return list.append(value), | |
| 61 | DestPtr.List => |list| try list.append(value), | |
| 62 | 62 | } |
| 63 | 63 | } |
| 64 | 64 | }; |
| ... | ... | @@ -96,12 +96,12 @@ pub const Parser = struct { |
| 96 | 96 | var stack = self.initUtilityArrayList(&ast.Node); |
| 97 | 97 | defer self.deinitUtilityArrayList(stack); |
| 98 | 98 | |
| 99 | stack.append(&root_node.base) %% unreachable; | |
| 99 | stack.append(&root_node.base) catch unreachable; | |
| 100 | 100 | while (stack.popOrNull()) |node| { |
| 101 | 101 | var i: usize = 0; |
| 102 | 102 | while (node.iterate(i)) |child| : (i += 1) { |
| 103 | 103 | if (child.iterate(0) != null) { |
| 104 | stack.append(child) %% unreachable; | |
| 104 | stack.append(child) catch unreachable; | |
| 105 | 105 | } else { |
| 106 | 106 | child.destroy(self.allocator); |
| 107 | 107 | } |
| ... | ... | @@ -111,7 +111,7 @@ pub const Parser = struct { |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | pub fn parse(self: &Parser) -> %&ast.NodeRoot { |
| 114 | const result = self.parseInner() %% |err| x: { | |
| 114 | const result = self.parseInner() catch |err| x: { | |
| 115 | 115 | if (self.cleanup_root_node) |root_node| { |
| 116 | 116 | self.freeAst(root_node); |
| 117 | 117 | } |
| ... | ... | @@ -126,10 +126,10 @@ pub const Parser = struct { |
| 126 | 126 | defer self.deinitUtilityArrayList(stack); |
| 127 | 127 | |
| 128 | 128 | const root_node = x: { |
| 129 | const root_node = %return self.createRoot(); | |
| 129 | const root_node = try self.createRoot(); | |
| 130 | 130 | %defer self.allocator.destroy(root_node); |
| 131 | 131 | // This stack append has to succeed for freeAst to work |
| 132 | %return stack.append(State.TopLevel); | |
| 132 | try stack.append(State.TopLevel); | |
| 133 | 133 | break :x root_node; |
| 134 | 134 | }; |
| 135 | 135 | assert(self.cleanup_root_node == null); |
| ... | ... | @@ -156,14 +156,14 @@ pub const Parser = struct { |
| 156 | 156 | const token = self.getNextToken(); |
| 157 | 157 | switch (token.id) { |
| 158 | 158 | Token.Id.Keyword_pub, Token.Id.Keyword_export => { |
| 159 | stack.append(State { .TopLevelExtern = token }) %% unreachable; | |
| 159 | stack.append(State { .TopLevelExtern = token }) catch unreachable; | |
| 160 | 160 | continue; |
| 161 | 161 | }, |
| 162 | 162 | Token.Id.Eof => return root_node, |
| 163 | 163 | else => { |
| 164 | 164 | self.putBackToken(token); |
| 165 | 165 | // TODO shouldn't need this cast |
| 166 | stack.append(State { .TopLevelExtern = null }) %% unreachable; | |
| 166 | stack.append(State { .TopLevelExtern = null }) catch unreachable; | |
| 167 | 167 | continue; |
| 168 | 168 | }, |
| 169 | 169 | } |
| ... | ... | @@ -176,7 +176,7 @@ pub const Parser = struct { |
| 176 | 176 | .visib_token = visib_token, |
| 177 | 177 | .extern_token = token, |
| 178 | 178 | }, |
| 179 | }) %% unreachable; | |
| 179 | }) catch unreachable; | |
| 180 | 180 | continue; |
| 181 | 181 | } |
| 182 | 182 | self.putBackToken(token); |
| ... | ... | @@ -185,52 +185,52 @@ pub const Parser = struct { |
| 185 | 185 | .visib_token = visib_token, |
| 186 | 186 | .extern_token = null, |
| 187 | 187 | }, |
| 188 | }) %% unreachable; | |
| 188 | }) catch unreachable; | |
| 189 | 189 | continue; |
| 190 | 190 | }, |
| 191 | 191 | State.TopLevelDecl => |ctx| { |
| 192 | 192 | const token = self.getNextToken(); |
| 193 | 193 | switch (token.id) { |
| 194 | 194 | Token.Id.Keyword_var, Token.Id.Keyword_const => { |
| 195 | stack.append(State.TopLevel) %% unreachable; | |
| 195 | stack.append(State.TopLevel) catch unreachable; | |
| 196 | 196 | // TODO shouldn't need these casts |
| 197 | const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, ctx.visib_token, | |
| 197 | const var_decl_node = try self.createAttachVarDecl(&root_node.decls, ctx.visib_token, | |
| 198 | 198 | token, (?Token)(null), ctx.extern_token); |
| 199 | %return stack.append(State { .VarDecl = var_decl_node }); | |
| 199 | try stack.append(State { .VarDecl = var_decl_node }); | |
| 200 | 200 | continue; |
| 201 | 201 | }, |
| 202 | 202 | Token.Id.Keyword_fn => { |
| 203 | stack.append(State.TopLevel) %% unreachable; | |
| 203 | stack.append(State.TopLevel) catch unreachable; | |
| 204 | 204 | // TODO shouldn't need these casts |
| 205 | const fn_proto = %return self.createAttachFnProto(&root_node.decls, token, | |
| 205 | const fn_proto = try self.createAttachFnProto(&root_node.decls, token, | |
| 206 | 206 | ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null)); |
| 207 | %return stack.append(State { .FnDef = fn_proto }); | |
| 208 | %return stack.append(State { .FnProto = fn_proto }); | |
| 207 | try stack.append(State { .FnDef = fn_proto }); | |
| 208 | try stack.append(State { .FnProto = fn_proto }); | |
| 209 | 209 | continue; |
| 210 | 210 | }, |
| 211 | 211 | Token.Id.StringLiteral => { |
| 212 | 212 | @panic("TODO extern with string literal"); |
| 213 | 213 | }, |
| 214 | 214 | Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => { |
| 215 | stack.append(State.TopLevel) %% unreachable; | |
| 216 | const fn_token = %return self.eatToken(Token.Id.Keyword_fn); | |
| 215 | stack.append(State.TopLevel) catch unreachable; | |
| 216 | const fn_token = try self.eatToken(Token.Id.Keyword_fn); | |
| 217 | 217 | // TODO shouldn't need this cast |
| 218 | const fn_proto = %return self.createAttachFnProto(&root_node.decls, fn_token, | |
| 218 | const fn_proto = try self.createAttachFnProto(&root_node.decls, fn_token, | |
| 219 | 219 | ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null)); |
| 220 | %return stack.append(State { .FnDef = fn_proto }); | |
| 221 | %return stack.append(State { .FnProto = fn_proto }); | |
| 220 | try stack.append(State { .FnDef = fn_proto }); | |
| 221 | try stack.append(State { .FnProto = fn_proto }); | |
| 222 | 222 | continue; |
| 223 | 223 | }, |
| 224 | 224 | else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)), |
| 225 | 225 | } |
| 226 | 226 | }, |
| 227 | 227 | State.VarDecl => |var_decl| { |
| 228 | var_decl.name_token = %return self.eatToken(Token.Id.Identifier); | |
| 229 | stack.append(State { .VarDeclAlign = var_decl }) %% unreachable; | |
| 228 | var_decl.name_token = try self.eatToken(Token.Id.Identifier); | |
| 229 | stack.append(State { .VarDeclAlign = var_decl }) catch unreachable; | |
| 230 | 230 | |
| 231 | 231 | const next_token = self.getNextToken(); |
| 232 | 232 | if (next_token.id == Token.Id.Colon) { |
| 233 | %return stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} }); | |
| 233 | try stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} }); | |
| 234 | 234 | continue; |
| 235 | 235 | } |
| 236 | 236 | |
| ... | ... | @@ -238,13 +238,13 @@ pub const Parser = struct { |
| 238 | 238 | continue; |
| 239 | 239 | }, |
| 240 | 240 | State.VarDeclAlign => |var_decl| { |
| 241 | stack.append(State { .VarDeclEq = var_decl }) %% unreachable; | |
| 241 | stack.append(State { .VarDeclEq = var_decl }) catch unreachable; | |
| 242 | 242 | |
| 243 | 243 | const next_token = self.getNextToken(); |
| 244 | 244 | if (next_token.id == Token.Id.Keyword_align) { |
| 245 | _ = %return self.eatToken(Token.Id.LParen); | |
| 246 | %return stack.append(State { .ExpectToken = Token.Id.RParen }); | |
| 247 | %return stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} }); | |
| 245 | _ = try self.eatToken(Token.Id.LParen); | |
| 246 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | |
| 247 | try stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} }); | |
| 248 | 248 | continue; |
| 249 | 249 | } |
| 250 | 250 | |
| ... | ... | @@ -255,8 +255,8 @@ pub const Parser = struct { |
| 255 | 255 | const token = self.getNextToken(); |
| 256 | 256 | if (token.id == Token.Id.Equal) { |
| 257 | 257 | var_decl.eq_token = token; |
| 258 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable; | |
| 259 | %return stack.append(State { | |
| 258 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; | |
| 259 | try stack.append(State { | |
| 260 | 260 | .Expression = DestPtr {.NullableField = &var_decl.init_node}, |
| 261 | 261 | }); |
| 262 | 262 | continue; |
| ... | ... | @@ -267,14 +267,14 @@ pub const Parser = struct { |
| 267 | 267 | return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id)); |
| 268 | 268 | }, |
| 269 | 269 | State.ExpectToken => |token_id| { |
| 270 | _ = %return self.eatToken(token_id); | |
| 270 | _ = try self.eatToken(token_id); | |
| 271 | 271 | continue; |
| 272 | 272 | }, |
| 273 | 273 | |
| 274 | 274 | State.Expression => |dest_ptr| { |
| 275 | 275 | // save the dest_ptr for later |
| 276 | stack.append(state) %% unreachable; | |
| 277 | %return stack.append(State.ExpectOperand); | |
| 276 | stack.append(state) catch unreachable; | |
| 277 | try stack.append(State.ExpectOperand); | |
| 278 | 278 | continue; |
| 279 | 279 | }, |
| 280 | 280 | State.ExpectOperand => { |
| ... | ... | @@ -283,13 +283,13 @@ pub const Parser = struct { |
| 283 | 283 | const token = self.getNextToken(); |
| 284 | 284 | switch (token.id) { |
| 285 | 285 | Token.Id.Keyword_return => { |
| 286 | %return stack.append(State { .PrefixOp = %return self.createPrefixOp(token, | |
| 286 | try stack.append(State { .PrefixOp = try self.createPrefixOp(token, | |
| 287 | 287 | ast.NodePrefixOp.PrefixOp.Return) }); |
| 288 | %return stack.append(State.ExpectOperand); | |
| 288 | try stack.append(State.ExpectOperand); | |
| 289 | 289 | continue; |
| 290 | 290 | }, |
| 291 | 291 | Token.Id.Ampersand => { |
| 292 | const prefix_op = %return self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{ | |
| 292 | const prefix_op = try self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{ | |
| 293 | 293 | .AddrOf = ast.NodePrefixOp.AddrOfInfo { |
| 294 | 294 | .align_expr = null, |
| 295 | 295 | .bit_offset_start_token = null, |
| ... | ... | @@ -298,30 +298,30 @@ pub const Parser = struct { |
| 298 | 298 | .volatile_token = null, |
| 299 | 299 | } |
| 300 | 300 | }); |
| 301 | %return stack.append(State { .PrefixOp = prefix_op }); | |
| 302 | %return stack.append(State.ExpectOperand); | |
| 303 | %return stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf }); | |
| 301 | try stack.append(State { .PrefixOp = prefix_op }); | |
| 302 | try stack.append(State.ExpectOperand); | |
| 303 | try stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf }); | |
| 304 | 304 | continue; |
| 305 | 305 | }, |
| 306 | 306 | Token.Id.Identifier => { |
| 307 | %return stack.append(State { | |
| 308 | .Operand = &(%return self.createIdentifier(token)).base | |
| 307 | try stack.append(State { | |
| 308 | .Operand = &(try self.createIdentifier(token)).base | |
| 309 | 309 | }); |
| 310 | %return stack.append(State.AfterOperand); | |
| 310 | try stack.append(State.AfterOperand); | |
| 311 | 311 | continue; |
| 312 | 312 | }, |
| 313 | 313 | Token.Id.IntegerLiteral => { |
| 314 | %return stack.append(State { | |
| 315 | .Operand = &(%return self.createIntegerLiteral(token)).base | |
| 314 | try stack.append(State { | |
| 315 | .Operand = &(try self.createIntegerLiteral(token)).base | |
| 316 | 316 | }); |
| 317 | %return stack.append(State.AfterOperand); | |
| 317 | try stack.append(State.AfterOperand); | |
| 318 | 318 | continue; |
| 319 | 319 | }, |
| 320 | 320 | Token.Id.FloatLiteral => { |
| 321 | %return stack.append(State { | |
| 322 | .Operand = &(%return self.createFloatLiteral(token)).base | |
| 321 | try stack.append(State { | |
| 322 | .Operand = &(try self.createFloatLiteral(token)).base | |
| 323 | 323 | }); |
| 324 | %return stack.append(State.AfterOperand); | |
| 324 | try stack.append(State.AfterOperand); | |
| 325 | 325 | continue; |
| 326 | 326 | }, |
| 327 | 327 | else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)), |
| ... | ... | @@ -335,17 +335,17 @@ pub const Parser = struct { |
| 335 | 335 | var token = self.getNextToken(); |
| 336 | 336 | switch (token.id) { |
| 337 | 337 | Token.Id.EqualEqual => { |
| 338 | %return stack.append(State { | |
| 339 | .InfixOp = %return self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual) | |
| 338 | try stack.append(State { | |
| 339 | .InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual) | |
| 340 | 340 | }); |
| 341 | %return stack.append(State.ExpectOperand); | |
| 341 | try stack.append(State.ExpectOperand); | |
| 342 | 342 | continue; |
| 343 | 343 | }, |
| 344 | 344 | Token.Id.BangEqual => { |
| 345 | %return stack.append(State { | |
| 346 | .InfixOp = %return self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual) | |
| 345 | try stack.append(State { | |
| 346 | .InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual) | |
| 347 | 347 | }); |
| 348 | %return stack.append(State.ExpectOperand); | |
| 348 | try stack.append(State.ExpectOperand); | |
| 349 | 349 | continue; |
| 350 | 350 | }, |
| 351 | 351 | else => { |
| ... | ... | @@ -357,7 +357,7 @@ pub const Parser = struct { |
| 357 | 357 | switch (stack.pop()) { |
| 358 | 358 | State.Expression => |dest_ptr| { |
| 359 | 359 | // we're done |
| 360 | %return dest_ptr.store(expression); | |
| 360 | try dest_ptr.store(expression); | |
| 361 | 361 | break; |
| 362 | 362 | }, |
| 363 | 363 | State.InfixOp => |infix_op| { |
| ... | ... | @@ -383,21 +383,21 @@ pub const Parser = struct { |
| 383 | 383 | var token = self.getNextToken(); |
| 384 | 384 | switch (token.id) { |
| 385 | 385 | Token.Id.Keyword_align => { |
| 386 | stack.append(state) %% unreachable; | |
| 386 | stack.append(state) catch unreachable; | |
| 387 | 387 | if (addr_of_info.align_expr != null) return self.parseError(token, "multiple align qualifiers"); |
| 388 | _ = %return self.eatToken(Token.Id.LParen); | |
| 389 | %return stack.append(State { .ExpectToken = Token.Id.RParen }); | |
| 390 | %return stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} }); | |
| 388 | _ = try self.eatToken(Token.Id.LParen); | |
| 389 | try stack.append(State { .ExpectToken = Token.Id.RParen }); | |
| 390 | try stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} }); | |
| 391 | 391 | continue; |
| 392 | 392 | }, |
| 393 | 393 | Token.Id.Keyword_const => { |
| 394 | stack.append(state) %% unreachable; | |
| 394 | stack.append(state) catch unreachable; | |
| 395 | 395 | if (addr_of_info.const_token != null) return self.parseError(token, "duplicate qualifier: const"); |
| 396 | 396 | addr_of_info.const_token = token; |
| 397 | 397 | continue; |
| 398 | 398 | }, |
| 399 | 399 | Token.Id.Keyword_volatile => { |
| 400 | stack.append(state) %% unreachable; | |
| 400 | stack.append(state) catch unreachable; | |
| 401 | 401 | if (addr_of_info.volatile_token != null) return self.parseError(token, "duplicate qualifier: volatile"); |
| 402 | 402 | addr_of_info.volatile_token = token; |
| 403 | 403 | continue; |
| ... | ... | @@ -416,14 +416,14 @@ pub const Parser = struct { |
| 416 | 416 | } |
| 417 | 417 | self.putBackToken(token); |
| 418 | 418 | |
| 419 | stack.append(State { .Expression = dest_ptr }) %% unreachable; | |
| 419 | stack.append(State { .Expression = dest_ptr }) catch unreachable; | |
| 420 | 420 | continue; |
| 421 | 421 | }, |
| 422 | 422 | |
| 423 | 423 | State.FnProto => |fn_proto| { |
| 424 | stack.append(State { .FnProtoAlign = fn_proto }) %% unreachable; | |
| 425 | %return stack.append(State { .ParamDecl = fn_proto }); | |
| 426 | %return stack.append(State { .ExpectToken = Token.Id.LParen }); | |
| 424 | stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable; | |
| 425 | try stack.append(State { .ParamDecl = fn_proto }); | |
| 426 | try stack.append(State { .ExpectToken = Token.Id.LParen }); | |
| 427 | 427 | |
| 428 | 428 | const next_token = self.getNextToken(); |
| 429 | 429 | if (next_token.id == Token.Id.Identifier) { |
| ... | ... | @@ -442,7 +442,7 @@ pub const Parser = struct { |
| 442 | 442 | if (token.id == Token.Id.Arrow) { |
| 443 | 443 | stack.append(State { |
| 444 | 444 | .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type}, |
| 445 | }) %% unreachable; | |
| 445 | }) catch unreachable; | |
| 446 | 446 | continue; |
| 447 | 447 | } else { |
| 448 | 448 | self.putBackToken(token); |
| ... | ... | @@ -455,7 +455,7 @@ pub const Parser = struct { |
| 455 | 455 | if (token.id == Token.Id.RParen) { |
| 456 | 456 | continue; |
| 457 | 457 | } |
| 458 | const param_decl = %return self.createAttachParamDecl(&fn_proto.params); | |
| 458 | const param_decl = try self.createAttachParamDecl(&fn_proto.params); | |
| 459 | 459 | if (token.id == Token.Id.Keyword_comptime) { |
| 460 | 460 | param_decl.comptime_token = token; |
| 461 | 461 | token = self.getNextToken(); |
| ... | ... | @@ -474,15 +474,15 @@ pub const Parser = struct { |
| 474 | 474 | } |
| 475 | 475 | if (token.id == Token.Id.Ellipsis3) { |
| 476 | 476 | param_decl.var_args_token = token; |
| 477 | stack.append(State { .ExpectToken = Token.Id.RParen }) %% unreachable; | |
| 477 | stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable; | |
| 478 | 478 | continue; |
| 479 | 479 | } else { |
| 480 | 480 | self.putBackToken(token); |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | stack.append(State { .ParamDecl = fn_proto }) %% unreachable; | |
| 484 | %return stack.append(State.ParamDeclComma); | |
| 485 | %return stack.append(State { | |
| 483 | stack.append(State { .ParamDecl = fn_proto }) catch unreachable; | |
| 484 | try stack.append(State.ParamDeclComma); | |
| 485 | try stack.append(State { | |
| 486 | 486 | .TypeExpr = DestPtr {.Field = &param_decl.type_node} |
| 487 | 487 | }); |
| 488 | 488 | continue; |
| ... | ... | @@ -504,9 +504,9 @@ pub const Parser = struct { |
| 504 | 504 | const token = self.getNextToken(); |
| 505 | 505 | switch(token.id) { |
| 506 | 506 | Token.Id.LBrace => { |
| 507 | const block = %return self.createBlock(token); | |
| 507 | const block = try self.createBlock(token); | |
| 508 | 508 | fn_proto.body_node = &block.base; |
| 509 | stack.append(State { .Block = block }) %% unreachable; | |
| 509 | stack.append(State { .Block = block }) catch unreachable; | |
| 510 | 510 | continue; |
| 511 | 511 | }, |
| 512 | 512 | Token.Id.Semicolon => continue, |
| ... | ... | @@ -523,8 +523,8 @@ pub const Parser = struct { |
| 523 | 523 | }, |
| 524 | 524 | else => { |
| 525 | 525 | self.putBackToken(token); |
| 526 | stack.append(State { .Block = block }) %% unreachable; | |
| 527 | %return stack.append(State { .Statement = block }); | |
| 526 | stack.append(State { .Block = block }) catch unreachable; | |
| 527 | try stack.append(State { .Statement = block }); | |
| 528 | 528 | continue; |
| 529 | 529 | }, |
| 530 | 530 | } |
| ... | ... | @@ -538,9 +538,9 @@ pub const Parser = struct { |
| 538 | 538 | const mut_token = self.getNextToken(); |
| 539 | 539 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 540 | 540 | // TODO shouldn't need these casts |
| 541 | const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null), | |
| 541 | const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null), | |
| 542 | 542 | mut_token, (?Token)(comptime_token), (?Token)(null)); |
| 543 | %return stack.append(State { .VarDecl = var_decl }); | |
| 543 | try stack.append(State { .VarDecl = var_decl }); | |
| 544 | 544 | continue; |
| 545 | 545 | } |
| 546 | 546 | self.putBackToken(mut_token); |
| ... | ... | @@ -552,16 +552,16 @@ pub const Parser = struct { |
| 552 | 552 | const mut_token = self.getNextToken(); |
| 553 | 553 | if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) { |
| 554 | 554 | // TODO shouldn't need these casts |
| 555 | const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null), | |
| 555 | const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null), | |
| 556 | 556 | mut_token, (?Token)(null), (?Token)(null)); |
| 557 | %return stack.append(State { .VarDecl = var_decl }); | |
| 557 | try stack.append(State { .VarDecl = var_decl }); | |
| 558 | 558 | continue; |
| 559 | 559 | } |
| 560 | 560 | self.putBackToken(mut_token); |
| 561 | 561 | } |
| 562 | 562 | |
| 563 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable; | |
| 564 | %return stack.append(State { .Expression = DestPtr{.List = &block.statements} }); | |
| 563 | stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable; | |
| 564 | try stack.append(State { .Expression = DestPtr{.List = &block.statements} }); | |
| 565 | 565 | continue; |
| 566 | 566 | }, |
| 567 | 567 | |
| ... | ... | @@ -576,7 +576,7 @@ pub const Parser = struct { |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | 578 | fn createRoot(self: &Parser) -> %&ast.NodeRoot { |
| 579 | const node = %return self.allocator.create(ast.NodeRoot); | |
| 579 | const node = try self.allocator.create(ast.NodeRoot); | |
| 580 | 580 | %defer self.allocator.destroy(node); |
| 581 | 581 | |
| 582 | 582 | *node = ast.NodeRoot { |
| ... | ... | @@ -589,7 +589,7 @@ pub const Parser = struct { |
| 589 | 589 | fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token, |
| 590 | 590 | extern_token: &const ?Token) -> %&ast.NodeVarDecl |
| 591 | 591 | { |
| 592 | const node = %return self.allocator.create(ast.NodeVarDecl); | |
| 592 | const node = try self.allocator.create(ast.NodeVarDecl); | |
| 593 | 593 | %defer self.allocator.destroy(node); |
| 594 | 594 | |
| 595 | 595 | *node = ast.NodeVarDecl { |
| ... | ... | @@ -612,7 +612,7 @@ pub const Parser = struct { |
| 612 | 612 | fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token, |
| 613 | 613 | cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&ast.NodeFnProto |
| 614 | 614 | { |
| 615 | const node = %return self.allocator.create(ast.NodeFnProto); | |
| 615 | const node = try self.allocator.create(ast.NodeFnProto); | |
| 616 | 616 | %defer self.allocator.destroy(node); |
| 617 | 617 | |
| 618 | 618 | *node = ast.NodeFnProto { |
| ... | ... | @@ -634,7 +634,7 @@ pub const Parser = struct { |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl { |
| 637 | const node = %return self.allocator.create(ast.NodeParamDecl); | |
| 637 | const node = try self.allocator.create(ast.NodeParamDecl); | |
| 638 | 638 | %defer self.allocator.destroy(node); |
| 639 | 639 | |
| 640 | 640 | *node = ast.NodeParamDecl { |
| ... | ... | @@ -649,7 +649,7 @@ pub const Parser = struct { |
| 649 | 649 | } |
| 650 | 650 | |
| 651 | 651 | fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock { |
| 652 | const node = %return self.allocator.create(ast.NodeBlock); | |
| 652 | const node = try self.allocator.create(ast.NodeBlock); | |
| 653 | 653 | %defer self.allocator.destroy(node); |
| 654 | 654 | |
| 655 | 655 | *node = ast.NodeBlock { |
| ... | ... | @@ -662,7 +662,7 @@ pub const Parser = struct { |
| 662 | 662 | } |
| 663 | 663 | |
| 664 | 664 | fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) -> %&ast.NodeInfixOp { |
| 665 | const node = %return self.allocator.create(ast.NodeInfixOp); | |
| 665 | const node = try self.allocator.create(ast.NodeInfixOp); | |
| 666 | 666 | %defer self.allocator.destroy(node); |
| 667 | 667 | |
| 668 | 668 | *node = ast.NodeInfixOp { |
| ... | ... | @@ -676,7 +676,7 @@ pub const Parser = struct { |
| 676 | 676 | } |
| 677 | 677 | |
| 678 | 678 | fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) -> %&ast.NodePrefixOp { |
| 679 | const node = %return self.allocator.create(ast.NodePrefixOp); | |
| 679 | const node = try self.allocator.create(ast.NodePrefixOp); | |
| 680 | 680 | %defer self.allocator.destroy(node); |
| 681 | 681 | |
| 682 | 682 | *node = ast.NodePrefixOp { |
| ... | ... | @@ -689,7 +689,7 @@ pub const Parser = struct { |
| 689 | 689 | } |
| 690 | 690 | |
| 691 | 691 | fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier { |
| 692 | const node = %return self.allocator.create(ast.NodeIdentifier); | |
| 692 | const node = try self.allocator.create(ast.NodeIdentifier); | |
| 693 | 693 | %defer self.allocator.destroy(node); |
| 694 | 694 | |
| 695 | 695 | *node = ast.NodeIdentifier { |
| ... | ... | @@ -700,7 +700,7 @@ pub const Parser = struct { |
| 700 | 700 | } |
| 701 | 701 | |
| 702 | 702 | fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral { |
| 703 | const node = %return self.allocator.create(ast.NodeIntegerLiteral); | |
| 703 | const node = try self.allocator.create(ast.NodeIntegerLiteral); | |
| 704 | 704 | %defer self.allocator.destroy(node); |
| 705 | 705 | |
| 706 | 706 | *node = ast.NodeIntegerLiteral { |
| ... | ... | @@ -711,7 +711,7 @@ pub const Parser = struct { |
| 711 | 711 | } |
| 712 | 712 | |
| 713 | 713 | fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral { |
| 714 | const node = %return self.allocator.create(ast.NodeFloatLiteral); | |
| 714 | const node = try self.allocator.create(ast.NodeFloatLiteral); | |
| 715 | 715 | %defer self.allocator.destroy(node); |
| 716 | 716 | |
| 717 | 717 | *node = ast.NodeFloatLiteral { |
| ... | ... | @@ -722,16 +722,16 @@ pub const Parser = struct { |
| 722 | 722 | } |
| 723 | 723 | |
| 724 | 724 | fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) -> %&ast.NodeIdentifier { |
| 725 | const node = %return self.createIdentifier(name_token); | |
| 725 | const node = try self.createIdentifier(name_token); | |
| 726 | 726 | %defer self.allocator.destroy(node); |
| 727 | %return dest_ptr.store(&node.base); | |
| 727 | try dest_ptr.store(&node.base); | |
| 728 | 728 | return node; |
| 729 | 729 | } |
| 730 | 730 | |
| 731 | 731 | fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl { |
| 732 | const node = %return self.createParamDecl(); | |
| 732 | const node = try self.createParamDecl(); | |
| 733 | 733 | %defer self.allocator.destroy(node); |
| 734 | %return list.append(&node.base); | |
| 734 | try list.append(&node.base); | |
| 735 | 735 | return node; |
| 736 | 736 | } |
| 737 | 737 | |
| ... | ... | @@ -739,18 +739,18 @@ pub const Parser = struct { |
| 739 | 739 | extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token, |
| 740 | 740 | inline_token: &const ?Token) -> %&ast.NodeFnProto |
| 741 | 741 | { |
| 742 | const node = %return self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token); | |
| 742 | const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token); | |
| 743 | 743 | %defer self.allocator.destroy(node); |
| 744 | %return list.append(&node.base); | |
| 744 | try list.append(&node.base); | |
| 745 | 745 | return node; |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | 748 | fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token, |
| 749 | 749 | mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&ast.NodeVarDecl |
| 750 | 750 | { |
| 751 | const node = %return self.createVarDecl(visib_token, mut_token, comptime_token, extern_token); | |
| 751 | const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token); | |
| 752 | 752 | %defer self.allocator.destroy(node); |
| 753 | %return list.append(&node.base); | |
| 753 | try list.append(&node.base); | |
| 754 | 754 | return node; |
| 755 | 755 | } |
| 756 | 756 | |
| ... | ... | @@ -783,7 +783,7 @@ pub const Parser = struct { |
| 783 | 783 | |
| 784 | 784 | fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token { |
| 785 | 785 | const token = self.getNextToken(); |
| 786 | %return self.expectToken(token, id); | |
| 786 | try self.expectToken(token, id); | |
| 787 | 787 | return token; |
| 788 | 788 | } |
| 789 | 789 | |
| ... | ... | @@ -812,7 +812,7 @@ pub const Parser = struct { |
| 812 | 812 | var stack = self.initUtilityArrayList(RenderAstFrame); |
| 813 | 813 | defer self.deinitUtilityArrayList(stack); |
| 814 | 814 | |
| 815 | %return stack.append(RenderAstFrame { | |
| 815 | try stack.append(RenderAstFrame { | |
| 816 | 816 | .node = &root_node.base, |
| 817 | 817 | .indent = 0, |
| 818 | 818 | }); |
| ... | ... | @@ -821,13 +821,13 @@ pub const Parser = struct { |
| 821 | 821 | { |
| 822 | 822 | var i: usize = 0; |
| 823 | 823 | while (i < frame.indent) : (i += 1) { |
| 824 | %return stream.print(" "); | |
| 824 | try stream.print(" "); | |
| 825 | 825 | } |
| 826 | 826 | } |
| 827 | %return stream.print("{}\n", @tagName(frame.node.id)); | |
| 827 | try stream.print("{}\n", @tagName(frame.node.id)); | |
| 828 | 828 | var child_i: usize = 0; |
| 829 | 829 | while (frame.node.iterate(child_i)) |child| : (child_i += 1) { |
| 830 | %return stack.append(RenderAstFrame { | |
| 830 | try stack.append(RenderAstFrame { | |
| 831 | 831 | .node = child, |
| 832 | 832 | .indent = frame.indent + 2, |
| 833 | 833 | }); |
| ... | ... | @@ -856,7 +856,7 @@ pub const Parser = struct { |
| 856 | 856 | while (i != 0) { |
| 857 | 857 | i -= 1; |
| 858 | 858 | const decl = root_node.decls.items[i]; |
| 859 | %return stack.append(RenderState {.TopLevelDecl = decl}); | |
| 859 | try stack.append(RenderState {.TopLevelDecl = decl}); | |
| 860 | 860 | } |
| 861 | 861 | } |
| 862 | 862 | |
| ... | ... | @@ -870,42 +870,42 @@ pub const Parser = struct { |
| 870 | 870 | const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl); |
| 871 | 871 | if (fn_proto.visib_token) |visib_token| { |
| 872 | 872 | switch (visib_token.id) { |
| 873 | Token.Id.Keyword_pub => %return stream.print("pub "), | |
| 874 | Token.Id.Keyword_export => %return stream.print("export "), | |
| 873 | Token.Id.Keyword_pub => try stream.print("pub "), | |
| 874 | Token.Id.Keyword_export => try stream.print("export "), | |
| 875 | 875 | else => unreachable, |
| 876 | 876 | } |
| 877 | 877 | } |
| 878 | 878 | if (fn_proto.extern_token) |extern_token| { |
| 879 | %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); | |
| 879 | try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); | |
| 880 | 880 | } |
| 881 | %return stream.print("fn"); | |
| 881 | try stream.print("fn"); | |
| 882 | 882 | |
| 883 | 883 | if (fn_proto.name_token) |name_token| { |
| 884 | %return stream.print(" {}", self.tokenizer.getTokenSlice(name_token)); | |
| 884 | try stream.print(" {}", self.tokenizer.getTokenSlice(name_token)); | |
| 885 | 885 | } |
| 886 | 886 | |
| 887 | %return stream.print("("); | |
| 887 | try stream.print("("); | |
| 888 | 888 | |
| 889 | %return stack.append(RenderState { .Text = "\n" }); | |
| 889 | try stack.append(RenderState { .Text = "\n" }); | |
| 890 | 890 | if (fn_proto.body_node == null) { |
| 891 | %return stack.append(RenderState { .Text = ";" }); | |
| 891 | try stack.append(RenderState { .Text = ";" }); | |
| 892 | 892 | } |
| 893 | 893 | |
| 894 | %return stack.append(RenderState { .FnProtoRParen = fn_proto}); | |
| 894 | try stack.append(RenderState { .FnProtoRParen = fn_proto}); | |
| 895 | 895 | var i = fn_proto.params.len; |
| 896 | 896 | while (i != 0) { |
| 897 | 897 | i -= 1; |
| 898 | 898 | const param_decl_node = fn_proto.params.items[i]; |
| 899 | %return stack.append(RenderState { .ParamDecl = param_decl_node}); | |
| 899 | try stack.append(RenderState { .ParamDecl = param_decl_node}); | |
| 900 | 900 | if (i != 0) { |
| 901 | %return stack.append(RenderState { .Text = ", " }); | |
| 901 | try stack.append(RenderState { .Text = ", " }); | |
| 902 | 902 | } |
| 903 | 903 | } |
| 904 | 904 | }, |
| 905 | 905 | ast.Node.Id.VarDecl => { |
| 906 | 906 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl); |
| 907 | %return stack.append(RenderState { .Text = "\n"}); | |
| 908 | %return stack.append(RenderState { .VarDecl = var_decl}); | |
| 907 | try stack.append(RenderState { .Text = "\n"}); | |
| 908 | try stack.append(RenderState { .VarDecl = var_decl}); | |
| 909 | 909 | |
| 910 | 910 | }, |
| 911 | 911 | else => unreachable, |
| ... | ... | @@ -914,111 +914,111 @@ pub const Parser = struct { |
| 914 | 914 | |
| 915 | 915 | RenderState.VarDecl => |var_decl| { |
| 916 | 916 | if (var_decl.visib_token) |visib_token| { |
| 917 | %return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); | |
| 917 | try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token)); | |
| 918 | 918 | } |
| 919 | 919 | if (var_decl.extern_token) |extern_token| { |
| 920 | %return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); | |
| 920 | try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token)); | |
| 921 | 921 | if (var_decl.lib_name != null) { |
| 922 | 922 | @panic("TODO"); |
| 923 | 923 | } |
| 924 | 924 | } |
| 925 | 925 | if (var_decl.comptime_token) |comptime_token| { |
| 926 | %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); | |
| 926 | try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); | |
| 927 | 927 | } |
| 928 | %return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token)); | |
| 929 | %return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token)); | |
| 928 | try stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token)); | |
| 929 | try stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token)); | |
| 930 | 930 | |
| 931 | %return stack.append(RenderState { .Text = ";" }); | |
| 931 | try stack.append(RenderState { .Text = ";" }); | |
| 932 | 932 | if (var_decl.init_node) |init_node| { |
| 933 | %return stack.append(RenderState { .Expression = init_node }); | |
| 934 | %return stack.append(RenderState { .Text = " = " }); | |
| 933 | try stack.append(RenderState { .Expression = init_node }); | |
| 934 | try stack.append(RenderState { .Text = " = " }); | |
| 935 | 935 | } |
| 936 | 936 | if (var_decl.align_node) |align_node| { |
| 937 | %return stack.append(RenderState { .Text = ")" }); | |
| 938 | %return stack.append(RenderState { .Expression = align_node }); | |
| 939 | %return stack.append(RenderState { .Text = " align(" }); | |
| 937 | try stack.append(RenderState { .Text = ")" }); | |
| 938 | try stack.append(RenderState { .Expression = align_node }); | |
| 939 | try stack.append(RenderState { .Text = " align(" }); | |
| 940 | 940 | } |
| 941 | 941 | if (var_decl.type_node) |type_node| { |
| 942 | %return stream.print(": "); | |
| 943 | %return stack.append(RenderState { .Expression = type_node }); | |
| 942 | try stream.print(": "); | |
| 943 | try stack.append(RenderState { .Expression = type_node }); | |
| 944 | 944 | } |
| 945 | 945 | }, |
| 946 | 946 | |
| 947 | 947 | RenderState.ParamDecl => |base| { |
| 948 | 948 | const param_decl = @fieldParentPtr(ast.NodeParamDecl, "base", base); |
| 949 | 949 | if (param_decl.comptime_token) |comptime_token| { |
| 950 | %return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); | |
| 950 | try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token)); | |
| 951 | 951 | } |
| 952 | 952 | if (param_decl.noalias_token) |noalias_token| { |
| 953 | %return stream.print("{} ", self.tokenizer.getTokenSlice(noalias_token)); | |
| 953 | try stream.print("{} ", self.tokenizer.getTokenSlice(noalias_token)); | |
| 954 | 954 | } |
| 955 | 955 | if (param_decl.name_token) |name_token| { |
| 956 | %return stream.print("{}: ", self.tokenizer.getTokenSlice(name_token)); | |
| 956 | try stream.print("{}: ", self.tokenizer.getTokenSlice(name_token)); | |
| 957 | 957 | } |
| 958 | 958 | if (param_decl.var_args_token) |var_args_token| { |
| 959 | %return stream.print("{}", self.tokenizer.getTokenSlice(var_args_token)); | |
| 959 | try stream.print("{}", self.tokenizer.getTokenSlice(var_args_token)); | |
| 960 | 960 | } else { |
| 961 | %return stack.append(RenderState { .Expression = param_decl.type_node}); | |
| 961 | try stack.append(RenderState { .Expression = param_decl.type_node}); | |
| 962 | 962 | } |
| 963 | 963 | }, |
| 964 | 964 | RenderState.Text => |bytes| { |
| 965 | %return stream.write(bytes); | |
| 965 | try stream.write(bytes); | |
| 966 | 966 | }, |
| 967 | 967 | RenderState.Expression => |base| switch (base.id) { |
| 968 | 968 | ast.Node.Id.Identifier => { |
| 969 | 969 | const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base); |
| 970 | %return stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token)); | |
| 970 | try stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token)); | |
| 971 | 971 | }, |
| 972 | 972 | ast.Node.Id.Block => { |
| 973 | 973 | const block = @fieldParentPtr(ast.NodeBlock, "base", base); |
| 974 | %return stream.write("{"); | |
| 975 | %return stack.append(RenderState { .Text = "}"}); | |
| 976 | %return stack.append(RenderState.PrintIndent); | |
| 977 | %return stack.append(RenderState { .Indent = indent}); | |
| 978 | %return stack.append(RenderState { .Text = "\n"}); | |
| 974 | try stream.write("{"); | |
| 975 | try stack.append(RenderState { .Text = "}"}); | |
| 976 | try stack.append(RenderState.PrintIndent); | |
| 977 | try stack.append(RenderState { .Indent = indent}); | |
| 978 | try stack.append(RenderState { .Text = "\n"}); | |
| 979 | 979 | var i = block.statements.len; |
| 980 | 980 | while (i != 0) { |
| 981 | 981 | i -= 1; |
| 982 | 982 | const statement_node = block.statements.items[i]; |
| 983 | %return stack.append(RenderState { .Statement = statement_node}); | |
| 984 | %return stack.append(RenderState.PrintIndent); | |
| 985 | %return stack.append(RenderState { .Indent = indent + indent_delta}); | |
| 986 | %return stack.append(RenderState { .Text = "\n" }); | |
| 983 | try stack.append(RenderState { .Statement = statement_node}); | |
| 984 | try stack.append(RenderState.PrintIndent); | |
| 985 | try stack.append(RenderState { .Indent = indent + indent_delta}); | |
| 986 | try stack.append(RenderState { .Text = "\n" }); | |
| 987 | 987 | } |
| 988 | 988 | }, |
| 989 | 989 | ast.Node.Id.InfixOp => { |
| 990 | 990 | const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base); |
| 991 | %return stack.append(RenderState { .Expression = prefix_op_node.rhs }); | |
| 991 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); | |
| 992 | 992 | switch (prefix_op_node.op) { |
| 993 | 993 | ast.NodeInfixOp.InfixOp.EqualEqual => { |
| 994 | %return stack.append(RenderState { .Text = " == "}); | |
| 994 | try stack.append(RenderState { .Text = " == "}); | |
| 995 | 995 | }, |
| 996 | 996 | ast.NodeInfixOp.InfixOp.BangEqual => { |
| 997 | %return stack.append(RenderState { .Text = " != "}); | |
| 997 | try stack.append(RenderState { .Text = " != "}); | |
| 998 | 998 | }, |
| 999 | 999 | else => unreachable, |
| 1000 | 1000 | } |
| 1001 | %return stack.append(RenderState { .Expression = prefix_op_node.lhs }); | |
| 1001 | try stack.append(RenderState { .Expression = prefix_op_node.lhs }); | |
| 1002 | 1002 | }, |
| 1003 | 1003 | ast.Node.Id.PrefixOp => { |
| 1004 | 1004 | const prefix_op_node = @fieldParentPtr(ast.NodePrefixOp, "base", base); |
| 1005 | %return stack.append(RenderState { .Expression = prefix_op_node.rhs }); | |
| 1005 | try stack.append(RenderState { .Expression = prefix_op_node.rhs }); | |
| 1006 | 1006 | switch (prefix_op_node.op) { |
| 1007 | 1007 | ast.NodePrefixOp.PrefixOp.Return => { |
| 1008 | %return stream.write("return "); | |
| 1008 | try stream.write("return "); | |
| 1009 | 1009 | }, |
| 1010 | 1010 | ast.NodePrefixOp.PrefixOp.AddrOf => |addr_of_info| { |
| 1011 | %return stream.write("&"); | |
| 1011 | try stream.write("&"); | |
| 1012 | 1012 | if (addr_of_info.volatile_token != null) { |
| 1013 | %return stack.append(RenderState { .Text = "volatile "}); | |
| 1013 | try stack.append(RenderState { .Text = "volatile "}); | |
| 1014 | 1014 | } |
| 1015 | 1015 | if (addr_of_info.const_token != null) { |
| 1016 | %return stack.append(RenderState { .Text = "const "}); | |
| 1016 | try stack.append(RenderState { .Text = "const "}); | |
| 1017 | 1017 | } |
| 1018 | 1018 | if (addr_of_info.align_expr) |align_expr| { |
| 1019 | %return stream.print("align("); | |
| 1020 | %return stack.append(RenderState { .Text = ") "}); | |
| 1021 | %return stack.append(RenderState { .Expression = align_expr}); | |
| 1019 | try stream.print("align("); | |
| 1020 | try stack.append(RenderState { .Text = ") "}); | |
| 1021 | try stack.append(RenderState { .Expression = align_expr}); | |
| 1022 | 1022 | } |
| 1023 | 1023 | }, |
| 1024 | 1024 | else => unreachable, |
| ... | ... | @@ -1026,42 +1026,42 @@ pub const Parser = struct { |
| 1026 | 1026 | }, |
| 1027 | 1027 | ast.Node.Id.IntegerLiteral => { |
| 1028 | 1028 | const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base); |
| 1029 | %return stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token)); | |
| 1029 | try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token)); | |
| 1030 | 1030 | }, |
| 1031 | 1031 | ast.Node.Id.FloatLiteral => { |
| 1032 | 1032 | const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base); |
| 1033 | %return stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token)); | |
| 1033 | try stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token)); | |
| 1034 | 1034 | }, |
| 1035 | 1035 | else => unreachable, |
| 1036 | 1036 | }, |
| 1037 | 1037 | RenderState.FnProtoRParen => |fn_proto| { |
| 1038 | %return stream.print(")"); | |
| 1038 | try stream.print(")"); | |
| 1039 | 1039 | if (fn_proto.align_expr != null) { |
| 1040 | 1040 | @panic("TODO"); |
| 1041 | 1041 | } |
| 1042 | 1042 | if (fn_proto.return_type) |return_type| { |
| 1043 | %return stream.print(" -> "); | |
| 1043 | try stream.print(" -> "); | |
| 1044 | 1044 | if (fn_proto.body_node) |body_node| { |
| 1045 | %return stack.append(RenderState { .Expression = body_node}); | |
| 1046 | %return stack.append(RenderState { .Text = " "}); | |
| 1045 | try stack.append(RenderState { .Expression = body_node}); | |
| 1046 | try stack.append(RenderState { .Text = " "}); | |
| 1047 | 1047 | } |
| 1048 | %return stack.append(RenderState { .Expression = return_type}); | |
| 1048 | try stack.append(RenderState { .Expression = return_type}); | |
| 1049 | 1049 | } |
| 1050 | 1050 | }, |
| 1051 | 1051 | RenderState.Statement => |base| { |
| 1052 | 1052 | switch (base.id) { |
| 1053 | 1053 | ast.Node.Id.VarDecl => { |
| 1054 | 1054 | const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base); |
| 1055 | %return stack.append(RenderState { .VarDecl = var_decl}); | |
| 1055 | try stack.append(RenderState { .VarDecl = var_decl}); | |
| 1056 | 1056 | }, |
| 1057 | 1057 | else => { |
| 1058 | %return stack.append(RenderState { .Text = ";"}); | |
| 1059 | %return stack.append(RenderState { .Expression = base}); | |
| 1058 | try stack.append(RenderState { .Text = ";"}); | |
| 1059 | try stack.append(RenderState { .Expression = base}); | |
| 1060 | 1060 | }, |
| 1061 | 1061 | } |
| 1062 | 1062 | }, |
| 1063 | 1063 | RenderState.Indent => |new_indent| indent = new_indent, |
| 1064 | RenderState.PrintIndent => %return stream.writeByteNTimes(' ', indent), | |
| 1064 | RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent), | |
| 1065 | 1065 | } |
| 1066 | 1066 | } |
| 1067 | 1067 | } |
| ... | ... | @@ -1096,12 +1096,12 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 { |
| 1096 | 1096 | var parser = Parser.init(&tokenizer, allocator, "(memory buffer)"); |
| 1097 | 1097 | defer parser.deinit(); |
| 1098 | 1098 | |
| 1099 | const root_node = %return parser.parse(); | |
| 1099 | const root_node = try parser.parse(); | |
| 1100 | 1100 | defer parser.freeAst(root_node); |
| 1101 | 1101 | |
| 1102 | var buffer = %return std.Buffer.initSize(allocator, 0); | |
| 1102 | var buffer = try std.Buffer.initSize(allocator, 0); | |
| 1103 | 1103 | var buffer_out_stream = io.BufferOutStream.init(&buffer); |
| 1104 | %return parser.renderSource(&buffer_out_stream.stream, root_node); | |
| 1104 | try parser.renderSource(&buffer_out_stream.stream, root_node); | |
| 1105 | 1105 | return buffer.toOwnedSlice(); |
| 1106 | 1106 | } |
| 1107 | 1107 | |
| ... | ... | @@ -1112,7 +1112,7 @@ fn testCanonical(source: []const u8) { |
| 1112 | 1112 | // Try it once with unlimited memory, make sure it works |
| 1113 | 1113 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); |
| 1114 | 1114 | var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize)); |
| 1115 | const result_source = testParse(source, &failing_allocator.allocator) %% @panic("test failed"); | |
| 1115 | const result_source = testParse(source, &failing_allocator.allocator) catch @panic("test failed"); | |
| 1116 | 1116 | if (!mem.eql(u8, result_source, source)) { |
| 1117 | 1117 | warn("\n====== expected this output: =========\n"); |
| 1118 | 1118 | warn("{}", source); |
src-self-hosted/target.zig+1-1| ... | ... | @@ -38,7 +38,7 @@ pub const Target = union(enum) { |
| 38 | 38 | |
| 39 | 39 | pub fn isDarwin(self: &const Target) -> bool { |
| 40 | 40 | return switch (self.getOs()) { |
| 41 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => true, | |
| 41 | builtin.Os.ios, builtin.Os.macosx => true, | |
| 42 | 42 | else => false, |
| 43 | 43 | }; |
| 44 | 44 | } |
src-self-hosted/tokenizer.zig+4-4| ... | ... | @@ -557,22 +557,22 @@ pub const Tokenizer = struct { |
| 557 | 557 | return 0; |
| 558 | 558 | } else { |
| 559 | 559 | // check utf8-encoded character. |
| 560 | const length = std.unicode.utf8ByteSequenceLength(c0) %% return 1; | |
| 560 | const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1; | |
| 561 | 561 | // the last 3 bytes in the buffer are guaranteed to be '\n', |
| 562 | 562 | // which means we don't need to do any bounds checking here. |
| 563 | 563 | const bytes = self.buffer[self.index..self.index + length]; |
| 564 | 564 | switch (length) { |
| 565 | 565 | 2 => { |
| 566 | const value = std.unicode.utf8Decode2(bytes) %% return length; | |
| 566 | const value = std.unicode.utf8Decode2(bytes) catch return length; | |
| 567 | 567 | if (value == 0x85) return length; // U+0085 (NEL) |
| 568 | 568 | }, |
| 569 | 569 | 3 => { |
| 570 | const value = std.unicode.utf8Decode3(bytes) %% return length; | |
| 570 | const value = std.unicode.utf8Decode3(bytes) catch return length; | |
| 571 | 571 | if (value == 0x2028) return length; // U+2028 (LS) |
| 572 | 572 | if (value == 0x2029) return length; // U+2029 (PS) |
| 573 | 573 | }, |
| 574 | 574 | 4 => { |
| 575 | _ = std.unicode.utf8Decode4(bytes) %% return length; | |
| 575 | _ = std.unicode.utf8Decode4(bytes) catch return length; | |
| 576 | 576 | }, |
| 577 | 577 | else => unreachable, |
| 578 | 578 | } |
src/all_types.hpp+7-12| ... | ... | @@ -37,13 +37,7 @@ struct ScopeDecls; |
| 37 | 37 | struct ZigWindowsSDK; |
| 38 | 38 | struct Tld; |
| 39 | 39 | struct TldExport; |
| 40 | ||
| 41 | struct IrGotoItem { | |
| 42 | AstNode *source_node; | |
| 43 | IrBasicBlock *bb; | |
| 44 | size_t instruction_index; | |
| 45 | Scope *scope; | |
| 46 | }; | |
| 40 | struct IrAnalyze; | |
| 47 | 41 | |
| 48 | 42 | struct IrExecutable { |
| 49 | 43 | ZigList<IrBasicBlock *> basic_block_list; |
| ... | ... | @@ -53,13 +47,13 @@ struct IrExecutable { |
| 53 | 47 | size_t *backward_branch_count; |
| 54 | 48 | size_t backward_branch_quota; |
| 55 | 49 | bool invalid; |
| 56 | ZigList<IrGotoItem> goto_list; | |
| 57 | 50 | bool is_inline; |
| 58 | 51 | FnTableEntry *fn_entry; |
| 59 | 52 | Buf *c_import_buf; |
| 60 | 53 | AstNode *source_node; |
| 61 | 54 | IrExecutable *parent_exec; |
| 62 | 55 | IrExecutable *source_exec; |
| 56 | IrAnalyze *analysis; | |
| 63 | 57 | Scope *begin_scope; |
| 64 | 58 | ZigList<Tld *> tld_list; |
| 65 | 59 | }; |
| ... | ... | @@ -395,7 +389,7 @@ enum NodeType { |
| 395 | 389 | NodeTypeArrayType, |
| 396 | 390 | NodeTypeErrorType, |
| 397 | 391 | NodeTypeVarLiteral, |
| 398 | NodeTypeTryExpr, | |
| 392 | NodeTypeIfErrorExpr, | |
| 399 | 393 | NodeTypeTestExpr, |
| 400 | 394 | }; |
| 401 | 395 | |
| ... | ... | @@ -552,7 +546,7 @@ struct AstNodeBinOpExpr { |
| 552 | 546 | AstNode *op2; |
| 553 | 547 | }; |
| 554 | 548 | |
| 555 | struct AstNodeUnwrapErrorExpr { | |
| 549 | struct AstNodeCatchExpr { | |
| 556 | 550 | AstNode *op1; |
| 557 | 551 | AstNode *symbol; // can be null |
| 558 | 552 | AstNode *op2; |
| ... | ... | @@ -866,7 +860,7 @@ struct AstNode { |
| 866 | 860 | AstNodeErrorValueDecl error_value_decl; |
| 867 | 861 | AstNodeTestDecl test_decl; |
| 868 | 862 | AstNodeBinOpExpr bin_op_expr; |
| 869 | AstNodeUnwrapErrorExpr unwrap_err_expr; | |
| 863 | AstNodeCatchExpr unwrap_err_expr; | |
| 870 | 864 | AstNodePrefixOpExpr prefix_op_expr; |
| 871 | 865 | AstNodeAddrOfExpr addr_of_expr; |
| 872 | 866 | AstNodeFnCallExpr fn_call_expr; |
| ... | ... | @@ -874,7 +868,7 @@ struct AstNode { |
| 874 | 868 | AstNodeSliceExpr slice_expr; |
| 875 | 869 | AstNodeUse use; |
| 876 | 870 | AstNodeIfBoolExpr if_bool_expr; |
| 877 | AstNodeTryExpr try_expr; | |
| 871 | AstNodeTryExpr if_err_expr; | |
| 878 | 872 | AstNodeTestExpr test_expr; |
| 879 | 873 | AstNodeWhileExpr while_expr; |
| 880 | 874 | AstNodeForExpr for_expr; |
| ... | ... | @@ -1626,6 +1620,7 @@ struct VariableTableEntry { |
| 1626 | 1620 | LLVMValueRef param_value_ref; |
| 1627 | 1621 | bool shadowable; |
| 1628 | 1622 | size_t mem_slot_index; |
| 1623 | IrExecutable *owner_exec; | |
| 1629 | 1624 | size_t ref_count; |
| 1630 | 1625 | VarLinkage linkage; |
| 1631 | 1626 | IrInstruction *decl_instruction; |
src/analyze.cpp+10-10| ... | ... | @@ -32,7 +32,7 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { |
| 32 | 32 | // failed semantic analysis, which isn't supposed to happen |
| 33 | 33 | ErrorMsg *err = add_node_error(g, node->owner->c_import_node, |
| 34 | 34 | buf_sprintf("compiler bug: @cImport generated invalid zig code")); |
| 35 | ||
| 35 | ||
| 36 | 36 | add_error_note(g, err, node, msg); |
| 37 | 37 | |
| 38 | 38 | g->errors.append(err); |
| ... | ... | @@ -2425,7 +2425,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { |
| 2425 | 2425 | qual_str = "extern"; |
| 2426 | 2426 | break; |
| 2427 | 2427 | } |
| 2428 | AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ? | |
| 2428 | AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ? | |
| 2429 | 2429 | decl_node->data.container_decl.init_arg_expr : decl_node; |
| 2430 | 2430 | add_node_error(g, source_node, |
| 2431 | 2431 | buf_sprintf("%s union does not support enum tag type", qual_str)); |
| ... | ... | @@ -2599,17 +2599,17 @@ void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, G |
| 2599 | 2599 | g->windows_subsystem_windows = false; |
| 2600 | 2600 | g->windows_subsystem_console = true; |
| 2601 | 2601 | } else if (buf_eql_str(symbol_name, "WinMain") && |
| 2602 | g->zig_target.os == ZigLLVM_Win32) | |
| 2602 | g->zig_target.os == OsWindows) | |
| 2603 | 2603 | { |
| 2604 | 2604 | g->have_winmain = true; |
| 2605 | 2605 | g->windows_subsystem_windows = true; |
| 2606 | 2606 | g->windows_subsystem_console = false; |
| 2607 | 2607 | } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && |
| 2608 | g->zig_target.os == ZigLLVM_Win32) | |
| 2608 | g->zig_target.os == OsWindows) | |
| 2609 | 2609 | { |
| 2610 | 2610 | g->have_winmain_crt_startup = true; |
| 2611 | 2611 | } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && |
| 2612 | g->zig_target.os == ZigLLVM_Win32) | |
| 2612 | g->zig_target.os == OsWindows) | |
| 2613 | 2613 | { |
| 2614 | 2614 | g->have_dllmain_crt_startup = true; |
| 2615 | 2615 | } |
| ... | ... | @@ -2933,7 +2933,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2933 | 2933 | case NodeTypeArrayType: |
| 2934 | 2934 | case NodeTypeErrorType: |
| 2935 | 2935 | case NodeTypeVarLiteral: |
| 2936 | case NodeTypeTryExpr: | |
| 2936 | case NodeTypeIfErrorExpr: | |
| 2937 | 2937 | case NodeTypeTestExpr: |
| 2938 | 2938 | zig_unreachable(); |
| 2939 | 2939 | } |
| ... | ... | @@ -3994,7 +3994,7 @@ void find_libc_include_path(CodeGen *g) { |
| 3994 | 3994 | if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) { |
| 3995 | 3995 | ZigWindowsSDK *sdk = get_windows_sdk(g); |
| 3996 | 3996 | |
| 3997 | if (g->zig_target.os == ZigLLVM_Win32) { | |
| 3997 | if (g->zig_target.os == OsWindows) { | |
| 3998 | 3998 | if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { |
| 3999 | 3999 | zig_panic("Unable to determine libc include path."); |
| 4000 | 4000 | } |
| ... | ... | @@ -4010,9 +4010,9 @@ void find_libc_include_path(CodeGen *g) { |
| 4010 | 4010 | void find_libc_lib_path(CodeGen *g) { |
| 4011 | 4011 | // later we can handle this better by reporting an error via the normal mechanism |
| 4012 | 4012 | if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0 || |
| 4013 | (g->zig_target.os == ZigLLVM_Win32 && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr))) | |
| 4013 | (g->zig_target.os == OsWindows && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr))) | |
| 4014 | 4014 | { |
| 4015 | if (g->zig_target.os == ZigLLVM_Win32) { | |
| 4015 | if (g->zig_target.os == OsWindows) { | |
| 4016 | 4016 | ZigWindowsSDK *sdk = get_windows_sdk(g); |
| 4017 | 4017 | |
| 4018 | 4018 | Buf* vc_lib_dir = buf_alloc(); |
| ... | ... | @@ -4039,7 +4039,7 @@ void find_libc_lib_path(CodeGen *g) { |
| 4039 | 4039 | } |
| 4040 | 4040 | |
| 4041 | 4041 | if (!g->libc_static_lib_dir || buf_len(g->libc_static_lib_dir) == 0) { |
| 4042 | if ((g->zig_target.os == ZigLLVM_Win32) && (g->msvc_lib_dir != NULL)) { | |
| 4042 | if ((g->zig_target.os == OsWindows) && (g->msvc_lib_dir != NULL)) { | |
| 4043 | 4043 | return; |
| 4044 | 4044 | } |
| 4045 | 4045 | else { |
src/ast_render.cpp+14-14| ... | ... | @@ -68,7 +68,7 @@ static const char *prefix_op_str(PrefixOp prefix_op) { |
| 68 | 68 | case PrefixOpDereference: return "*"; |
| 69 | 69 | case PrefixOpMaybe: return "?"; |
| 70 | 70 | case PrefixOpError: return "%"; |
| 71 | case PrefixOpUnwrapError: return "%%"; | |
| 71 | case PrefixOpUnwrapError: return "catch"; | |
| 72 | 72 | case PrefixOpUnwrapMaybe: return "??"; |
| 73 | 73 | } |
| 74 | 74 | zig_unreachable(); |
| ... | ... | @@ -85,7 +85,7 @@ static const char *visib_mod_string(VisibMod mod) { |
| 85 | 85 | static const char *return_string(ReturnKind kind) { |
| 86 | 86 | switch (kind) { |
| 87 | 87 | case ReturnKindUnconditional: return "return"; |
| 88 | case ReturnKindError: return "%return"; | |
| 88 | case ReturnKindError: return "try"; | |
| 89 | 89 | } |
| 90 | 90 | zig_unreachable(); |
| 91 | 91 | } |
| ... | ... | @@ -241,8 +241,8 @@ static const char *node_type_str(NodeType node_type) { |
| 241 | 241 | return "ErrorType"; |
| 242 | 242 | case NodeTypeVarLiteral: |
| 243 | 243 | return "VarLiteral"; |
| 244 | case NodeTypeTryExpr: | |
| 245 | return "TryExpr"; | |
| 244 | case NodeTypeIfErrorExpr: | |
| 245 | return "IfErrorExpr"; | |
| 246 | 246 | case NodeTypeTestExpr: |
| 247 | 247 | return "TestExpr"; |
| 248 | 248 | } |
| ... | ... | @@ -872,23 +872,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 872 | 872 | fprintf(ar->f, "null"); |
| 873 | 873 | break; |
| 874 | 874 | } |
| 875 | case NodeTypeTryExpr: | |
| 875 | case NodeTypeIfErrorExpr: | |
| 876 | 876 | { |
| 877 | 877 | fprintf(ar->f, "if ("); |
| 878 | render_node_grouped(ar, node->data.try_expr.target_node); | |
| 878 | render_node_grouped(ar, node->data.if_err_expr.target_node); | |
| 879 | 879 | fprintf(ar->f, ") "); |
| 880 | if (node->data.try_expr.var_symbol) { | |
| 881 | const char *ptr_str = node->data.try_expr.var_is_ptr ? "*" : ""; | |
| 882 | const char *var_name = buf_ptr(node->data.try_expr.var_symbol); | |
| 880 | if (node->data.if_err_expr.var_symbol) { | |
| 881 | const char *ptr_str = node->data.if_err_expr.var_is_ptr ? "*" : ""; | |
| 882 | const char *var_name = buf_ptr(node->data.if_err_expr.var_symbol); | |
| 883 | 883 | fprintf(ar->f, "|%s%s| ", ptr_str, var_name); |
| 884 | 884 | } |
| 885 | render_node_grouped(ar, node->data.try_expr.then_node); | |
| 886 | if (node->data.try_expr.else_node) { | |
| 885 | render_node_grouped(ar, node->data.if_err_expr.then_node); | |
| 886 | if (node->data.if_err_expr.else_node) { | |
| 887 | 887 | fprintf(ar->f, " else "); |
| 888 | if (node->data.try_expr.err_symbol) { | |
| 889 | fprintf(ar->f, "|%s| ", buf_ptr(node->data.try_expr.err_symbol)); | |
| 888 | if (node->data.if_err_expr.err_symbol) { | |
| 889 | fprintf(ar->f, "|%s| ", buf_ptr(node->data.if_err_expr.err_symbol)); | |
| 890 | 890 | } |
| 891 | render_node_grouped(ar, node->data.try_expr.else_node); | |
| 891 | render_node_grouped(ar, node->data.if_err_expr.else_node); | |
| 892 | 892 | } |
| 893 | 893 | break; |
| 894 | 894 | } |
src/codegen.cpp+13-15| ... | ... | @@ -42,7 +42,7 @@ static void init_darwin_native(CodeGen *g) { |
| 42 | 42 | g->mmacosx_version_min = buf_create_from_str(osx_target); |
| 43 | 43 | } else if (ios_target) { |
| 44 | 44 | g->mios_version_min = buf_create_from_str(ios_target); |
| 45 | } else if (g->zig_target.os != ZigLLVM_IOS) { | |
| 45 | } else if (g->zig_target.os != OsIOS) { | |
| 46 | 46 | g->mmacosx_version_min = buf_create_from_str("10.10"); |
| 47 | 47 | } |
| 48 | 48 | } |
| ... | ... | @@ -136,9 +136,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 136 | 136 | g->each_lib_rpath = true; |
| 137 | 137 | #endif |
| 138 | 138 | |
| 139 | if (g->zig_target.os == ZigLLVM_Darwin || | |
| 140 | g->zig_target.os == ZigLLVM_MacOSX || | |
| 141 | g->zig_target.os == ZigLLVM_IOS) | |
| 139 | if (g->zig_target.os == OsMacOSX || | |
| 140 | g->zig_target.os == OsIOS) | |
| 142 | 141 | { |
| 143 | 142 | init_darwin_native(g); |
| 144 | 143 | } |
| ... | ... | @@ -146,9 +145,8 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out |
| 146 | 145 | } |
| 147 | 146 | |
| 148 | 147 | // On Darwin/MacOS/iOS, we always link libSystem which contains libc. |
| 149 | if (g->zig_target.os == ZigLLVM_Darwin || | |
| 150 | g->zig_target.os == ZigLLVM_MacOSX || | |
| 151 | g->zig_target.os == ZigLLVM_IOS) | |
| 148 | if (g->zig_target.os == OsMacOSX || | |
| 149 | g->zig_target.os == OsIOS) | |
| 152 | 150 | { |
| 153 | 151 | g->libc_link_lib = create_link_lib(buf_create_from_str("c")); |
| 154 | 152 | g->link_libs_list.append(g->libc_link_lib); |
| ... | ... | @@ -363,7 +361,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 363 | 361 | g->zig_target.arch.arch == ZigLLVM_x86_64) |
| 364 | 362 | { |
| 365 | 363 | // cold calling convention is not supported on windows |
| 366 | if (g->zig_target.os == ZigLLVM_Win32) { | |
| 364 | if (g->zig_target.os == OsWindows) { | |
| 367 | 365 | return LLVMCCallConv; |
| 368 | 366 | } else { |
| 369 | 367 | return LLVMColdCallConv; |
| ... | ... | @@ -386,7 +384,7 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { |
| 386 | 384 | } |
| 387 | 385 | |
| 388 | 386 | static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { |
| 389 | if (g->zig_target.os == ZigLLVM_Win32) { | |
| 387 | if (g->zig_target.os == OsWindows) { | |
| 390 | 388 | addLLVMFnAttr(fn_val, "uwtable"); |
| 391 | 389 | } |
| 392 | 390 | } |
| ... | ... | @@ -559,7 +557,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 559 | 557 | } |
| 560 | 558 | // Note: byval is disabled on windows due to an LLVM bug: |
| 561 | 559 | // https://github.com/zig-lang/zig/issues/536 |
| 562 | if (is_byval && g->zig_target.os != ZigLLVM_Win32) { | |
| 560 | if (is_byval && g->zig_target.os != OsWindows) { | |
| 563 | 561 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval"); |
| 564 | 562 | } |
| 565 | 563 | } |
| ... | ... | @@ -2371,7 +2369,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2371 | 2369 | FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; |
| 2372 | 2370 | // Note: byval is disabled on windows due to an LLVM bug: |
| 2373 | 2371 | // https://github.com/zig-lang/zig/issues/536 |
| 2374 | if (gen_info->is_byval && g->zig_target.os != ZigLLVM_Win32) { | |
| 2372 | if (gen_info->is_byval && g->zig_target.os != OsWindows) { | |
| 2375 | 2373 | addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval"); |
| 2376 | 2374 | } |
| 2377 | 2375 | } |
| ... | ... | @@ -5094,7 +5092,7 @@ static void define_builtin_compile_vars(CodeGen *g) { |
| 5094 | 5092 | buf_appendf(contents, "pub const Os = enum {\n"); |
| 5095 | 5093 | uint32_t field_count = (uint32_t)target_os_count(); |
| 5096 | 5094 | for (uint32_t i = 0; i < field_count; i += 1) { |
| 5097 | ZigLLVM_OSType os_type = get_target_os(i); | |
| 5095 | Os os_type = get_target_os(i); | |
| 5098 | 5096 | const char *name = get_target_os_name(os_type); |
| 5099 | 5097 | buf_appendf(contents, " %s,\n", name); |
| 5100 | 5098 | |
| ... | ... | @@ -5304,7 +5302,7 @@ static void init(CodeGen *g) { |
| 5304 | 5302 | // LLVM creates invalid binaries on Windows sometimes. |
| 5305 | 5303 | // See https://github.com/zig-lang/zig/issues/508 |
| 5306 | 5304 | // As a workaround we do not use target native features on Windows. |
| 5307 | if (g->zig_target.os == ZigLLVM_Win32) { | |
| 5305 | if (g->zig_target.os == OsWindows) { | |
| 5308 | 5306 | target_specific_cpu_args = ""; |
| 5309 | 5307 | target_specific_features = ""; |
| 5310 | 5308 | } else { |
| ... | ... | @@ -5524,13 +5522,13 @@ static void gen_root_source(CodeGen *g) { |
| 5524 | 5522 | } |
| 5525 | 5523 | report_errors_and_maybe_exit(g); |
| 5526 | 5524 | |
| 5527 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && | |
| 5525 | if (!g->is_test_build && g->zig_target.os != OsFreestanding && | |
| 5528 | 5526 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && |
| 5529 | 5527 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| 5530 | 5528 | { |
| 5531 | 5529 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig"); |
| 5532 | 5530 | } |
| 5533 | if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { | |
| 5531 | if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { | |
| 5534 | 5532 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); |
| 5535 | 5533 | } |
| 5536 | 5534 |
src/ir.cpp+75-53| ... | ... | @@ -2530,8 +2530,10 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s |
| 2530 | 2530 | bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) |
| 2531 | 2531 | { |
| 2532 | 2532 | VariableTableEntry *var = create_local_var(irb->codegen, node, scope, name, src_is_const, gen_is_const, is_shadowable, is_comptime); |
| 2533 | if (is_comptime != nullptr || gen_is_const) | |
| 2533 | if (is_comptime != nullptr || gen_is_const) { | |
| 2534 | 2534 | var->mem_slot_index = exec_next_mem_slot(irb->exec); |
| 2535 | var->owner_exec = irb->exec; | |
| 2536 | } | |
| 2535 | 2537 | assert(var->child_scope); |
| 2536 | 2538 | return var; |
| 2537 | 2539 | } |
| ... | ... | @@ -3896,22 +3898,21 @@ static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *n |
| 3896 | 3898 | align_value, bit_offset_start, bit_offset_end); |
| 3897 | 3899 | } |
| 3898 | 3900 | |
| 3899 | static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { | |
| 3900 | assert(node->type == NodeTypePrefixOpExpr); | |
| 3901 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; | |
| 3902 | ||
| 3901 | static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, | |
| 3902 | LVal lval) | |
| 3903 | { | |
| 3903 | 3904 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); |
| 3904 | 3905 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3905 | 3906 | return irb->codegen->invalid_instruction; |
| 3906 | 3907 | |
| 3907 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, true); | |
| 3908 | IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); | |
| 3908 | 3909 | if (payload_ptr == irb->codegen->invalid_instruction) |
| 3909 | 3910 | return irb->codegen->invalid_instruction; |
| 3910 | 3911 | |
| 3911 | 3912 | if (lval.is_ptr) |
| 3912 | 3913 | return payload_ptr; |
| 3913 | 3914 | |
| 3914 | return ir_build_load_ptr(irb, scope, node, payload_ptr); | |
| 3915 | return ir_build_load_ptr(irb, scope, source_node, payload_ptr); | |
| 3915 | 3916 | } |
| 3916 | 3917 | |
| 3917 | 3918 | static IrInstruction *ir_gen_maybe_assert_ok(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { |
| ... | ... | @@ -3963,7 +3964,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 3963 | 3964 | case PrefixOpError: |
| 3964 | 3965 | return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpError), lval); |
| 3965 | 3966 | case PrefixOpUnwrapError: |
| 3966 | return ir_gen_err_assert_ok(irb, scope, node, lval); | |
| 3967 | return ir_gen_err_assert_ok(irb, scope, node, node->data.prefix_op_expr.primary_expr, lval); | |
| 3967 | 3968 | case PrefixOpUnwrapMaybe: |
| 3968 | 3969 | return ir_gen_maybe_assert_ok(irb, scope, node, lval); |
| 3969 | 3970 | } |
| ... | ... | @@ -4663,16 +4664,16 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no |
| 4663 | 4664 | return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); |
| 4664 | 4665 | } |
| 4665 | 4666 | |
| 4666 | static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | |
| 4667 | assert(node->type == NodeTypeTryExpr); | |
| 4667 | static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | |
| 4668 | assert(node->type == NodeTypeIfErrorExpr); | |
| 4668 | 4669 | |
| 4669 | AstNode *target_node = node->data.try_expr.target_node; | |
| 4670 | AstNode *then_node = node->data.try_expr.then_node; | |
| 4671 | AstNode *else_node = node->data.try_expr.else_node; | |
| 4672 | bool var_is_ptr = node->data.try_expr.var_is_ptr; | |
| 4670 | AstNode *target_node = node->data.if_err_expr.target_node; | |
| 4671 | AstNode *then_node = node->data.if_err_expr.then_node; | |
| 4672 | AstNode *else_node = node->data.if_err_expr.else_node; | |
| 4673 | bool var_is_ptr = node->data.if_err_expr.var_is_ptr; | |
| 4673 | 4674 | bool var_is_const = true; |
| 4674 | Buf *var_symbol = node->data.try_expr.var_symbol; | |
| 4675 | Buf *err_symbol = node->data.try_expr.err_symbol; | |
| 4675 | Buf *var_symbol = node->data.if_err_expr.var_symbol; | |
| 4676 | Buf *err_symbol = node->data.if_err_expr.err_symbol; | |
| 4676 | 4677 | |
| 4677 | 4678 | IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR); |
| 4678 | 4679 | if (err_val_ptr == irb->codegen->invalid_instruction) |
| ... | ... | @@ -5179,6 +5180,17 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN |
| 5179 | 5180 | AstNode *op2_node = node->data.unwrap_err_expr.op2; |
| 5180 | 5181 | AstNode *var_node = node->data.unwrap_err_expr.symbol; |
| 5181 | 5182 | |
| 5183 | if (op2_node->type == NodeTypeUnreachable) { | |
| 5184 | if (var_node != nullptr) { | |
| 5185 | assert(var_node->type == NodeTypeSymbol); | |
| 5186 | Buf *var_name = var_node->data.symbol_expr.symbol; | |
| 5187 | add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); | |
| 5188 | return irb->codegen->invalid_instruction; | |
| 5189 | } | |
| 5190 | return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LVAL_NONE); | |
| 5191 | } | |
| 5192 | ||
| 5193 | ||
| 5182 | 5194 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LVAL_PTR); |
| 5183 | 5195 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 5184 | 5196 | return irb->codegen->invalid_instruction; |
| ... | ... | @@ -5409,8 +5421,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 5409 | 5421 | return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); |
| 5410 | 5422 | case NodeTypeVarLiteral: |
| 5411 | 5423 | return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval); |
| 5412 | case NodeTypeTryExpr: | |
| 5413 | return ir_lval_wrap(irb, scope, ir_gen_try_expr(irb, scope, node), lval); | |
| 5424 | case NodeTypeIfErrorExpr: | |
| 5425 | return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); | |
| 5414 | 5426 | case NodeTypeTestExpr: |
| 5415 | 5427 | return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval); |
| 5416 | 5428 | case NodeTypeSwitchExpr: |
| ... | ... | @@ -7037,48 +7049,48 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 7037 | 7049 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 7038 | 7050 | return codegen->invalid_instruction; |
| 7039 | 7051 | |
| 7040 | IrExecutable ir_executable = {0}; | |
| 7041 | ir_executable.source_node = source_node; | |
| 7042 | ir_executable.parent_exec = parent_exec; | |
| 7043 | ir_executable.name = exec_name; | |
| 7044 | ir_executable.is_inline = true; | |
| 7045 | ir_executable.fn_entry = fn_entry; | |
| 7046 | ir_executable.c_import_buf = c_import_buf; | |
| 7047 | ir_executable.begin_scope = scope; | |
| 7048 | ir_gen(codegen, node, scope, &ir_executable); | |
| 7049 | ||
| 7050 | if (ir_executable.invalid) | |
| 7052 | IrExecutable *ir_executable = allocate<IrExecutable>(1); | |
| 7053 | ir_executable->source_node = source_node; | |
| 7054 | ir_executable->parent_exec = parent_exec; | |
| 7055 | ir_executable->name = exec_name; | |
| 7056 | ir_executable->is_inline = true; | |
| 7057 | ir_executable->fn_entry = fn_entry; | |
| 7058 | ir_executable->c_import_buf = c_import_buf; | |
| 7059 | ir_executable->begin_scope = scope; | |
| 7060 | ir_gen(codegen, node, scope, ir_executable); | |
| 7061 | ||
| 7062 | if (ir_executable->invalid) | |
| 7051 | 7063 | return codegen->invalid_instruction; |
| 7052 | 7064 | |
| 7053 | 7065 | if (codegen->verbose_ir) { |
| 7054 | 7066 | fprintf(stderr, "\nSource: "); |
| 7055 | 7067 | ast_render(codegen, stderr, node, 4); |
| 7056 | 7068 | fprintf(stderr, "\n{ // (IR)\n"); |
| 7057 | ir_print(codegen, stderr, &ir_executable, 4); | |
| 7069 | ir_print(codegen, stderr, ir_executable, 4); | |
| 7058 | 7070 | fprintf(stderr, "}\n"); |
| 7059 | 7071 | } |
| 7060 | IrExecutable analyzed_executable = {0}; | |
| 7061 | analyzed_executable.source_node = source_node; | |
| 7062 | analyzed_executable.parent_exec = parent_exec; | |
| 7063 | analyzed_executable.source_exec = &ir_executable; | |
| 7064 | analyzed_executable.name = exec_name; | |
| 7065 | analyzed_executable.is_inline = true; | |
| 7066 | analyzed_executable.fn_entry = fn_entry; | |
| 7067 | analyzed_executable.c_import_buf = c_import_buf; | |
| 7068 | analyzed_executable.backward_branch_count = backward_branch_count; | |
| 7069 | analyzed_executable.backward_branch_quota = backward_branch_quota; | |
| 7070 | analyzed_executable.begin_scope = scope; | |
| 7071 | TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node); | |
| 7072 | IrExecutable *analyzed_executable = allocate<IrExecutable>(1); | |
| 7073 | analyzed_executable->source_node = source_node; | |
| 7074 | analyzed_executable->parent_exec = parent_exec; | |
| 7075 | analyzed_executable->source_exec = ir_executable; | |
| 7076 | analyzed_executable->name = exec_name; | |
| 7077 | analyzed_executable->is_inline = true; | |
| 7078 | analyzed_executable->fn_entry = fn_entry; | |
| 7079 | analyzed_executable->c_import_buf = c_import_buf; | |
| 7080 | analyzed_executable->backward_branch_count = backward_branch_count; | |
| 7081 | analyzed_executable->backward_branch_quota = backward_branch_quota; | |
| 7082 | analyzed_executable->begin_scope = scope; | |
| 7083 | TypeTableEntry *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, node); | |
| 7072 | 7084 | if (type_is_invalid(result_type)) |
| 7073 | 7085 | return codegen->invalid_instruction; |
| 7074 | 7086 | |
| 7075 | 7087 | if (codegen->verbose_ir) { |
| 7076 | 7088 | fprintf(stderr, "{ // (analyzed)\n"); |
| 7077 | ir_print(codegen, stderr, &analyzed_executable, 4); | |
| 7089 | ir_print(codegen, stderr, analyzed_executable, 4); | |
| 7078 | 7090 | fprintf(stderr, "}\n"); |
| 7079 | 7091 | } |
| 7080 | 7092 | |
| 7081 | return ir_exec_const_result(codegen, &analyzed_executable); | |
| 7093 | return ir_exec_const_result(codegen, analyzed_executable); | |
| 7082 | 7094 | } |
| 7083 | 7095 | |
| 7084 | 7096 | static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| ... | ... | @@ -9334,6 +9346,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9334 | 9346 | IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); |
| 9335 | 9347 | bool is_comptime_var = ir_get_var_is_comptime(var); |
| 9336 | 9348 | |
| 9349 | bool var_class_requires_const = false; | |
| 9350 | ||
| 9337 | 9351 | TypeTableEntry *result_type = casted_init_value->value.type; |
| 9338 | 9352 | if (type_is_invalid(result_type)) { |
| 9339 | 9353 | result_type = ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -9345,6 +9359,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9345 | 9359 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 9346 | 9360 | break; |
| 9347 | 9361 | case VarClassRequiredConst: |
| 9362 | var_class_requires_const = true; | |
| 9348 | 9363 | if (!var->src_is_const && !is_comptime_var) { |
| 9349 | 9364 | ir_add_error_node(ira, source_node, |
| 9350 | 9365 | buf_sprintf("variable of type '%s' must be const or comptime", |
| ... | ... | @@ -9366,8 +9381,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9366 | 9381 | return ira->codegen->builtin_types.entry_void; |
| 9367 | 9382 | } |
| 9368 | 9383 | |
| 9369 | bool is_comptime = ir_get_var_is_comptime(var); | |
| 9370 | ||
| 9371 | 9384 | if (decl_var_instruction->align_value == nullptr) { |
| 9372 | 9385 | var->align_bytes = get_abi_alignment(ira->codegen, result_type); |
| 9373 | 9386 | } else { |
| ... | ... | @@ -9382,12 +9395,12 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 9382 | 9395 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 9383 | 9396 | *mem_slot = casted_init_value->value; |
| 9384 | 9397 | |
| 9385 | if (is_comptime) { | |
| 9398 | if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { | |
| 9386 | 9399 | ir_build_const_from(ira, &decl_var_instruction->base); |
| 9387 | 9400 | return ira->codegen->builtin_types.entry_void; |
| 9388 | 9401 | } |
| 9389 | 9402 | } |
| 9390 | } else if (is_comptime) { | |
| 9403 | } else if (is_comptime_var) { | |
| 9391 | 9404 | ir_add_error(ira, &decl_var_instruction->base, |
| 9392 | 9405 | buf_sprintf("cannot store runtime value in compile time variable")); |
| 9393 | 9406 | var->value->type = ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -9690,6 +9703,10 @@ static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t in |
| 9690 | 9703 | static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 9691 | 9704 | VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) |
| 9692 | 9705 | { |
| 9706 | if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { | |
| 9707 | assert(ira->codegen->errors.length != 0); | |
| 9708 | return ira->codegen->invalid_instruction; | |
| 9709 | } | |
| 9693 | 9710 | assert(var->value->type); |
| 9694 | 9711 | if (type_is_invalid(var->value->type)) |
| 9695 | 9712 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -9700,9 +9717,14 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 9700 | 9717 | if (var->value->special == ConstValSpecialStatic) { |
| 9701 | 9718 | mem_slot = var->value; |
| 9702 | 9719 | } else { |
| 9703 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. | |
| 9704 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) | |
| 9705 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | |
| 9720 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { | |
| 9721 | // find the relevant exec_context | |
| 9722 | assert(var->owner_exec != nullptr); | |
| 9723 | assert(var->owner_exec->analysis != nullptr); | |
| 9724 | IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; | |
| 9725 | assert(var->mem_slot_index < exec_context->mem_slot_count); | |
| 9726 | mem_slot = &exec_context->mem_slot_list[var->mem_slot_index]; | |
| 9727 | } | |
| 9706 | 9728 | } |
| 9707 | 9729 | |
| 9708 | 9730 | bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; |
| ... | ... | @@ -15328,8 +15350,8 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl |
| 15328 | 15350 | assert(!old_exec->invalid); |
| 15329 | 15351 | assert(expected_type == nullptr || !type_is_invalid(expected_type)); |
| 15330 | 15352 | |
| 15331 | IrAnalyze ir_analyze_data = {}; | |
| 15332 | IrAnalyze *ira = &ir_analyze_data; | |
| 15353 | IrAnalyze *ira = allocate<IrAnalyze>(1); | |
| 15354 | old_exec->analysis = ira; | |
| 15333 | 15355 | ira->codegen = codegen; |
| 15334 | 15356 | ira->explicit_return_type = expected_type; |
| 15335 | 15357 |
src/link.cpp+8-1| ... | ... | @@ -334,6 +334,13 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 334 | 334 | if (!g->is_native_target) { |
| 335 | 335 | lj->args.append("--allow-shlib-undefined"); |
| 336 | 336 | } |
| 337 | ||
| 338 | if (g->zig_target.os == OsZen) { | |
| 339 | lj->args.append("-e"); | |
| 340 | lj->args.append("main"); | |
| 341 | ||
| 342 | lj->args.append("--image-base=0x10000000"); | |
| 343 | } | |
| 337 | 344 | } |
| 338 | 345 | |
| 339 | 346 | //static bool is_target_cyg_mingw(const ZigTarget *target) { |
| ... | ... | @@ -644,7 +651,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { |
| 644 | 651 | platform->kind = MacOS; |
| 645 | 652 | } else if (g->mios_version_min) { |
| 646 | 653 | platform->kind = IPhoneOS; |
| 647 | } else if (g->zig_target.os == ZigLLVM_MacOSX || g->zig_target.os == ZigLLVM_Darwin) { | |
| 654 | } else if (g->zig_target.os == OsMacOSX) { | |
| 648 | 655 | platform->kind = MacOS; |
| 649 | 656 | g->mmacosx_version_min = buf_create_from_str("10.10"); |
| 650 | 657 | } else { |
src/main.cpp+1-1| ... | ... | @@ -120,7 +120,7 @@ static int print_target_list(FILE *f) { |
| 120 | 120 | fprintf(f, "\nOperating Systems:\n"); |
| 121 | 121 | size_t os_count = target_os_count(); |
| 122 | 122 | for (size_t i = 0; i < os_count; i += 1) { |
| 123 | ZigLLVM_OSType os_type = get_target_os(i); | |
| 123 | Os os_type = get_target_os(i); | |
| 124 | 124 | const char *native_str = (native.os == os_type) ? " (native)" : ""; |
| 125 | 125 | fprintf(f, " %s%s\n", get_target_os_name(os_type), native_str); |
| 126 | 126 | } |
src/parser.cpp+50-46| ... | ... | @@ -225,6 +225,7 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index); |
| 225 | 225 | static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory); |
| 226 | 226 | static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory); |
| 227 | 227 | static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory); |
| 228 | static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index); | |
| 228 | 229 | |
| 229 | 230 | static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) { |
| 230 | 231 | if (token->id == token_id) { |
| ... | ... | @@ -1003,25 +1004,21 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) { |
| 1003 | 1004 | |
| 1004 | 1005 | /* |
| 1005 | 1006 | PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression |
| 1006 | PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | |
| 1007 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try" | |
| 1007 | 1008 | */ |
| 1008 | 1009 | static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 1009 | 1010 | Token *token = &pc->tokens->at(*token_index); |
| 1010 | 1011 | if (token->id == TokenIdAmpersand) { |
| 1011 | 1012 | return ast_parse_addr_of(pc, token_index); |
| 1012 | 1013 | } |
| 1014 | if (token->id == TokenIdKeywordTry) { | |
| 1015 | return ast_parse_try_expr(pc, token_index); | |
| 1016 | } | |
| 1013 | 1017 | PrefixOp prefix_op = tok_to_prefix_op(token); |
| 1014 | 1018 | if (prefix_op == PrefixOpInvalid) { |
| 1015 | 1019 | return ast_parse_suffix_op_expr(pc, token_index, mandatory); |
| 1016 | 1020 | } |
| 1017 | 1021 | |
| 1018 | if (prefix_op == PrefixOpError || prefix_op == PrefixOpMaybe) { | |
| 1019 | Token *maybe_return = &pc->tokens->at(*token_index + 1); | |
| 1020 | if (maybe_return->id == TokenIdKeywordReturn) { | |
| 1021 | return ast_parse_return_expr(pc, token_index); | |
| 1022 | } | |
| 1023 | } | |
| 1024 | ||
| 1025 | 1022 | *token_index += 1; |
| 1026 | 1023 | |
| 1027 | 1024 | |
| ... | ... | @@ -1410,15 +1407,15 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index |
| 1410 | 1407 | } |
| 1411 | 1408 | |
| 1412 | 1409 | if (err_name_tok != nullptr) { |
| 1413 | AstNode *node = ast_create_node(pc, NodeTypeTryExpr, if_token); | |
| 1414 | node->data.try_expr.target_node = condition; | |
| 1415 | node->data.try_expr.var_is_ptr = var_is_ptr; | |
| 1410 | AstNode *node = ast_create_node(pc, NodeTypeIfErrorExpr, if_token); | |
| 1411 | node->data.if_err_expr.target_node = condition; | |
| 1412 | node->data.if_err_expr.var_is_ptr = var_is_ptr; | |
| 1416 | 1413 | if (var_name_tok != nullptr) { |
| 1417 | node->data.try_expr.var_symbol = token_buf(var_name_tok); | |
| 1414 | node->data.if_err_expr.var_symbol = token_buf(var_name_tok); | |
| 1418 | 1415 | } |
| 1419 | node->data.try_expr.then_node = body_node; | |
| 1420 | node->data.try_expr.err_symbol = token_buf(err_name_tok); | |
| 1421 | node->data.try_expr.else_node = else_node; | |
| 1416 | node->data.if_err_expr.then_node = body_node; | |
| 1417 | node->data.if_err_expr.err_symbol = token_buf(err_name_tok); | |
| 1418 | node->data.if_err_expr.else_node = else_node; | |
| 1422 | 1419 | return node; |
| 1423 | 1420 | } else if (var_name_tok != nullptr) { |
| 1424 | 1421 | AstNode *node = ast_create_node(pc, NodeTypeTestExpr, if_token); |
| ... | ... | @@ -1438,38 +1435,41 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index |
| 1438 | 1435 | } |
| 1439 | 1436 | |
| 1440 | 1437 | /* |
| 1441 | ReturnExpression : option("%") "return" option(Expression) | |
| 1438 | ReturnExpression : "return" option(Expression) | |
| 1442 | 1439 | */ |
| 1443 | 1440 | static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) { |
| 1444 | 1441 | Token *token = &pc->tokens->at(*token_index); |
| 1445 | 1442 | |
| 1446 | NodeType node_type; | |
| 1447 | ReturnKind kind; | |
| 1448 | ||
| 1449 | if (token->id == TokenIdPercent) { | |
| 1450 | Token *next_token = &pc->tokens->at(*token_index + 1); | |
| 1451 | if (next_token->id == TokenIdKeywordReturn) { | |
| 1452 | kind = ReturnKindError; | |
| 1453 | node_type = NodeTypeReturnExpr; | |
| 1454 | *token_index += 2; | |
| 1455 | } else { | |
| 1456 | return nullptr; | |
| 1457 | } | |
| 1458 | } else if (token->id == TokenIdKeywordReturn) { | |
| 1459 | kind = ReturnKindUnconditional; | |
| 1460 | node_type = NodeTypeReturnExpr; | |
| 1461 | *token_index += 1; | |
| 1462 | } else { | |
| 1443 | if (token->id != TokenIdKeywordReturn) { | |
| 1463 | 1444 | return nullptr; |
| 1464 | 1445 | } |
| 1446 | *token_index += 1; | |
| 1465 | 1447 | |
| 1466 | AstNode *node = ast_create_node(pc, node_type, token); | |
| 1467 | node->data.return_expr.kind = kind; | |
| 1448 | AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token); | |
| 1449 | node->data.return_expr.kind = ReturnKindUnconditional; | |
| 1468 | 1450 | node->data.return_expr.expr = ast_parse_expression(pc, token_index, false); |
| 1469 | 1451 | |
| 1470 | 1452 | return node; |
| 1471 | 1453 | } |
| 1472 | 1454 | |
| 1455 | /* | |
| 1456 | TryExpression : "try" Expression | |
| 1457 | */ | |
| 1458 | static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index) { | |
| 1459 | Token *token = &pc->tokens->at(*token_index); | |
| 1460 | ||
| 1461 | if (token->id != TokenIdKeywordTry) { | |
| 1462 | return nullptr; | |
| 1463 | } | |
| 1464 | *token_index += 1; | |
| 1465 | ||
| 1466 | AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token); | |
| 1467 | node->data.return_expr.kind = ReturnKindError; | |
| 1468 | node->data.return_expr.expr = ast_parse_expression(pc, token_index, true); | |
| 1469 | ||
| 1470 | return node; | |
| 1471 | } | |
| 1472 | ||
| 1473 | 1473 | /* |
| 1474 | 1474 | BreakExpression = "break" option(":" Symbol) option(Expression) |
| 1475 | 1475 | */ |
| ... | ... | @@ -2041,7 +2041,7 @@ static BinOpType ast_parse_ass_op(ParseContext *pc, size_t *token_index, bool ma |
| 2041 | 2041 | /* |
| 2042 | 2042 | UnwrapExpression : BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression |
| 2043 | 2043 | UnwrapMaybe : "??" BoolOrExpression |
| 2044 | UnwrapError : "%%" option("|" "Symbol" "|") BoolOrExpression | |
| 2044 | UnwrapError = "catch" option("|" Symbol "|") Expression | |
| 2045 | 2045 | */ |
| 2046 | 2046 | static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2047 | 2047 | AstNode *lhs = ast_parse_bool_or_expr(pc, token_index, mandatory); |
| ... | ... | @@ -2061,7 +2061,7 @@ static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, boo |
| 2061 | 2061 | node->data.bin_op_expr.op2 = rhs; |
| 2062 | 2062 | |
| 2063 | 2063 | return node; |
| 2064 | } else if (token->id == TokenIdPercentPercent) { | |
| 2064 | } else if (token->id == TokenIdKeywordCatch) { | |
| 2065 | 2065 | *token_index += 1; |
| 2066 | 2066 | |
| 2067 | 2067 | AstNode *node = ast_create_node(pc, NodeTypeUnwrapErrorExpr, token); |
| ... | ... | @@ -2124,7 +2124,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in |
| 2124 | 2124 | } |
| 2125 | 2125 | |
| 2126 | 2126 | /* |
| 2127 | Expression = ReturnExpression | BreakExpression | AssignmentExpression | |
| 2127 | Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression | |
| 2128 | 2128 | */ |
| 2129 | 2129 | static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2130 | 2130 | Token *token = &pc->tokens->at(*token_index); |
| ... | ... | @@ -2133,6 +2133,10 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool |
| 2133 | 2133 | if (return_expr) |
| 2134 | 2134 | return return_expr; |
| 2135 | 2135 | |
| 2136 | AstNode *try_expr = ast_parse_try_expr(pc, token_index); | |
| 2137 | if (try_expr) | |
| 2138 | return try_expr; | |
| 2139 | ||
| 2136 | 2140 | AstNode *break_expr = ast_parse_break_expr(pc, token_index); |
| 2137 | 2141 | if (break_expr) |
| 2138 | 2142 | return break_expr; |
| ... | ... | @@ -2153,10 +2157,10 @@ static bool statement_terminates_without_semicolon(AstNode *node) { |
| 2153 | 2157 | if (node->data.if_bool_expr.else_node) |
| 2154 | 2158 | return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node); |
| 2155 | 2159 | return node->data.if_bool_expr.then_block->type == NodeTypeBlock; |
| 2156 | case NodeTypeTryExpr: | |
| 2157 | if (node->data.try_expr.else_node) | |
| 2158 | return statement_terminates_without_semicolon(node->data.try_expr.else_node); | |
| 2159 | return node->data.try_expr.then_node->type == NodeTypeBlock; | |
| 2160 | case NodeTypeIfErrorExpr: | |
| 2161 | if (node->data.if_err_expr.else_node) | |
| 2162 | return statement_terminates_without_semicolon(node->data.if_err_expr.else_node); | |
| 2163 | return node->data.if_err_expr.then_node->type == NodeTypeBlock; | |
| 2160 | 2164 | case NodeTypeTestExpr: |
| 2161 | 2165 | if (node->data.test_expr.else_node) |
| 2162 | 2166 | return statement_terminates_without_semicolon(node->data.test_expr.else_node); |
| ... | ... | @@ -2829,10 +2833,10 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2829 | 2833 | visit_field(&node->data.if_bool_expr.then_block, visit, context); |
| 2830 | 2834 | visit_field(&node->data.if_bool_expr.else_node, visit, context); |
| 2831 | 2835 | break; |
| 2832 | case NodeTypeTryExpr: | |
| 2833 | visit_field(&node->data.try_expr.target_node, visit, context); | |
| 2834 | visit_field(&node->data.try_expr.then_node, visit, context); | |
| 2835 | visit_field(&node->data.try_expr.else_node, visit, context); | |
| 2836 | case NodeTypeIfErrorExpr: | |
| 2837 | visit_field(&node->data.if_err_expr.target_node, visit, context); | |
| 2838 | visit_field(&node->data.if_err_expr.then_node, visit, context); | |
| 2839 | visit_field(&node->data.if_err_expr.else_node, visit, context); | |
| 2836 | 2840 | break; |
| 2837 | 2841 | case NodeTypeTestExpr: |
| 2838 | 2842 | visit_field(&node->data.test_expr.target_node, visit, context); |
src/target.cpp+257-81| ... | ... | @@ -127,39 +127,39 @@ static const ZigLLVM_VendorType vendor_list[] = { |
| 127 | 127 | ZigLLVM_SUSE, |
| 128 | 128 | }; |
| 129 | 129 | |
| 130 | static const ZigLLVM_OSType os_list[] = { | |
| 131 | ZigLLVM_UnknownOS, | |
| 132 | ZigLLVM_Ananas, | |
| 133 | ZigLLVM_CloudABI, | |
| 134 | ZigLLVM_Darwin, | |
| 135 | ZigLLVM_DragonFly, | |
| 136 | ZigLLVM_FreeBSD, | |
| 137 | ZigLLVM_Fuchsia, | |
| 138 | ZigLLVM_IOS, | |
| 139 | ZigLLVM_KFreeBSD, | |
| 140 | ZigLLVM_Linux, | |
| 141 | ZigLLVM_Lv2, | |
| 142 | ZigLLVM_MacOSX, | |
| 143 | ZigLLVM_NetBSD, | |
| 144 | ZigLLVM_OpenBSD, | |
| 145 | ZigLLVM_Solaris, | |
| 146 | ZigLLVM_Win32, | |
| 147 | ZigLLVM_Haiku, | |
| 148 | ZigLLVM_Minix, | |
| 149 | ZigLLVM_RTEMS, | |
| 150 | ZigLLVM_NaCl, | |
| 151 | ZigLLVM_CNK, | |
| 152 | ZigLLVM_Bitrig, | |
| 153 | ZigLLVM_AIX, | |
| 154 | ZigLLVM_CUDA, | |
| 155 | ZigLLVM_NVCL, | |
| 156 | ZigLLVM_AMDHSA, | |
| 157 | ZigLLVM_PS4, | |
| 158 | ZigLLVM_ELFIAMCU, | |
| 159 | ZigLLVM_TvOS, | |
| 160 | ZigLLVM_WatchOS, | |
| 161 | ZigLLVM_Mesa3D, | |
| 162 | ZigLLVM_Contiki, | |
| 130 | static const Os os_list[] = { | |
| 131 | OsFreestanding, | |
| 132 | OsAnanas, | |
| 133 | OsCloudABI, | |
| 134 | OsDragonFly, | |
| 135 | OsFreeBSD, | |
| 136 | OsFuchsia, | |
| 137 | OsIOS, | |
| 138 | OsKFreeBSD, | |
| 139 | OsLinux, | |
| 140 | OsLv2, // PS3 | |
| 141 | OsMacOSX, | |
| 142 | OsNetBSD, | |
| 143 | OsOpenBSD, | |
| 144 | OsSolaris, | |
| 145 | OsWindows, | |
| 146 | OsHaiku, | |
| 147 | OsMinix, | |
| 148 | OsRTEMS, | |
| 149 | OsNaCl, // Native Client | |
| 150 | OsCNK, // BG/P Compute-Node Kernel | |
| 151 | OsBitrig, | |
| 152 | OsAIX, | |
| 153 | OsCUDA, // NVIDIA CUDA | |
| 154 | OsNVCL, // NVIDIA OpenCL | |
| 155 | OsAMDHSA, // AMD HSA Runtime | |
| 156 | OsPS4, | |
| 157 | OsELFIAMCU, | |
| 158 | OsTvOS, // Apple tvOS | |
| 159 | OsWatchOS, // Apple watchOS | |
| 160 | OsMesa3D, | |
| 161 | OsContiki, | |
| 162 | OsZen, | |
| 163 | 163 | }; |
| 164 | 164 | |
| 165 | 165 | static const ZigLLVM_EnvironmentType environ_list[] = { |
| ... | ... | @@ -233,12 +233,187 @@ ZigLLVM_VendorType get_target_vendor(size_t index) { |
| 233 | 233 | size_t target_os_count(void) { |
| 234 | 234 | return array_length(os_list); |
| 235 | 235 | } |
| 236 | ZigLLVM_OSType get_target_os(size_t index) { | |
| 236 | Os get_target_os(size_t index) { | |
| 237 | 237 | return os_list[index]; |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | const char *get_target_os_name(ZigLLVM_OSType os_type) { | |
| 241 | return (os_type == ZigLLVM_UnknownOS) ? "freestanding" : ZigLLVMGetOSTypeName(os_type); | |
| 240 | static ZigLLVM_OSType get_llvm_os_type(Os os_type) { | |
| 241 | switch (os_type) { | |
| 242 | case OsFreestanding: | |
| 243 | case OsZen: | |
| 244 | return ZigLLVM_UnknownOS; | |
| 245 | case OsAnanas: | |
| 246 | return ZigLLVM_Ananas; | |
| 247 | case OsCloudABI: | |
| 248 | return ZigLLVM_CloudABI; | |
| 249 | case OsDragonFly: | |
| 250 | return ZigLLVM_DragonFly; | |
| 251 | case OsFreeBSD: | |
| 252 | return ZigLLVM_FreeBSD; | |
| 253 | case OsFuchsia: | |
| 254 | return ZigLLVM_Fuchsia; | |
| 255 | case OsIOS: | |
| 256 | return ZigLLVM_IOS; | |
| 257 | case OsKFreeBSD: | |
| 258 | return ZigLLVM_KFreeBSD; | |
| 259 | case OsLinux: | |
| 260 | return ZigLLVM_Linux; | |
| 261 | case OsLv2: | |
| 262 | return ZigLLVM_Lv2; | |
| 263 | case OsMacOSX: | |
| 264 | return ZigLLVM_MacOSX; | |
| 265 | case OsNetBSD: | |
| 266 | return ZigLLVM_NetBSD; | |
| 267 | case OsOpenBSD: | |
| 268 | return ZigLLVM_OpenBSD; | |
| 269 | case OsSolaris: | |
| 270 | return ZigLLVM_Solaris; | |
| 271 | case OsWindows: | |
| 272 | return ZigLLVM_Win32; | |
| 273 | case OsHaiku: | |
| 274 | return ZigLLVM_Haiku; | |
| 275 | case OsMinix: | |
| 276 | return ZigLLVM_Minix; | |
| 277 | case OsRTEMS: | |
| 278 | return ZigLLVM_RTEMS; | |
| 279 | case OsNaCl: | |
| 280 | return ZigLLVM_NaCl; | |
| 281 | case OsCNK: | |
| 282 | return ZigLLVM_CNK; | |
| 283 | case OsBitrig: | |
| 284 | return ZigLLVM_Bitrig; | |
| 285 | case OsAIX: | |
| 286 | return ZigLLVM_AIX; | |
| 287 | case OsCUDA: | |
| 288 | return ZigLLVM_CUDA; | |
| 289 | case OsNVCL: | |
| 290 | return ZigLLVM_NVCL; | |
| 291 | case OsAMDHSA: | |
| 292 | return ZigLLVM_AMDHSA; | |
| 293 | case OsPS4: | |
| 294 | return ZigLLVM_PS4; | |
| 295 | case OsELFIAMCU: | |
| 296 | return ZigLLVM_ELFIAMCU; | |
| 297 | case OsTvOS: | |
| 298 | return ZigLLVM_TvOS; | |
| 299 | case OsWatchOS: | |
| 300 | return ZigLLVM_WatchOS; | |
| 301 | case OsMesa3D: | |
| 302 | return ZigLLVM_Mesa3D; | |
| 303 | case OsContiki: | |
| 304 | return ZigLLVM_Contiki; | |
| 305 | } | |
| 306 | zig_unreachable(); | |
| 307 | } | |
| 308 | ||
| 309 | static Os get_zig_os_type(ZigLLVM_OSType os_type) { | |
| 310 | switch (os_type) { | |
| 311 | case ZigLLVM_UnknownOS: | |
| 312 | return OsFreestanding; | |
| 313 | case ZigLLVM_Ananas: | |
| 314 | return OsAnanas; | |
| 315 | case ZigLLVM_CloudABI: | |
| 316 | return OsCloudABI; | |
| 317 | case ZigLLVM_DragonFly: | |
| 318 | return OsDragonFly; | |
| 319 | case ZigLLVM_FreeBSD: | |
| 320 | return OsFreeBSD; | |
| 321 | case ZigLLVM_Fuchsia: | |
| 322 | return OsFuchsia; | |
| 323 | case ZigLLVM_IOS: | |
| 324 | return OsIOS; | |
| 325 | case ZigLLVM_KFreeBSD: | |
| 326 | return OsKFreeBSD; | |
| 327 | case ZigLLVM_Linux: | |
| 328 | return OsLinux; | |
| 329 | case ZigLLVM_Lv2: | |
| 330 | return OsLv2; | |
| 331 | case ZigLLVM_Darwin: | |
| 332 | case ZigLLVM_MacOSX: | |
| 333 | return OsMacOSX; | |
| 334 | case ZigLLVM_NetBSD: | |
| 335 | return OsNetBSD; | |
| 336 | case ZigLLVM_OpenBSD: | |
| 337 | return OsOpenBSD; | |
| 338 | case ZigLLVM_Solaris: | |
| 339 | return OsSolaris; | |
| 340 | case ZigLLVM_Win32: | |
| 341 | return OsWindows; | |
| 342 | case ZigLLVM_Haiku: | |
| 343 | return OsHaiku; | |
| 344 | case ZigLLVM_Minix: | |
| 345 | return OsMinix; | |
| 346 | case ZigLLVM_RTEMS: | |
| 347 | return OsRTEMS; | |
| 348 | case ZigLLVM_NaCl: | |
| 349 | return OsNaCl; | |
| 350 | case ZigLLVM_CNK: | |
| 351 | return OsCNK; | |
| 352 | case ZigLLVM_Bitrig: | |
| 353 | return OsBitrig; | |
| 354 | case ZigLLVM_AIX: | |
| 355 | return OsAIX; | |
| 356 | case ZigLLVM_CUDA: | |
| 357 | return OsCUDA; | |
| 358 | case ZigLLVM_NVCL: | |
| 359 | return OsNVCL; | |
| 360 | case ZigLLVM_AMDHSA: | |
| 361 | return OsAMDHSA; | |
| 362 | case ZigLLVM_PS4: | |
| 363 | return OsPS4; | |
| 364 | case ZigLLVM_ELFIAMCU: | |
| 365 | return OsELFIAMCU; | |
| 366 | case ZigLLVM_TvOS: | |
| 367 | return OsTvOS; | |
| 368 | case ZigLLVM_WatchOS: | |
| 369 | return OsWatchOS; | |
| 370 | case ZigLLVM_Mesa3D: | |
| 371 | return OsMesa3D; | |
| 372 | case ZigLLVM_Contiki: | |
| 373 | return OsContiki; | |
| 374 | } | |
| 375 | zig_unreachable(); | |
| 376 | } | |
| 377 | ||
| 378 | const char *get_target_os_name(Os os_type) { | |
| 379 | switch (os_type) { | |
| 380 | case OsFreestanding: | |
| 381 | return "freestanding"; | |
| 382 | case OsZen: | |
| 383 | return "zen"; | |
| 384 | case OsAnanas: | |
| 385 | case OsCloudABI: | |
| 386 | case OsDragonFly: | |
| 387 | case OsFreeBSD: | |
| 388 | case OsFuchsia: | |
| 389 | case OsIOS: | |
| 390 | case OsKFreeBSD: | |
| 391 | case OsLinux: | |
| 392 | case OsLv2: // PS3 | |
| 393 | case OsMacOSX: | |
| 394 | case OsNetBSD: | |
| 395 | case OsOpenBSD: | |
| 396 | case OsSolaris: | |
| 397 | case OsWindows: | |
| 398 | case OsHaiku: | |
| 399 | case OsMinix: | |
| 400 | case OsRTEMS: | |
| 401 | case OsNaCl: // Native Client | |
| 402 | case OsCNK: // BG/P Compute-Node Kernel | |
| 403 | case OsBitrig: | |
| 404 | case OsAIX: | |
| 405 | case OsCUDA: // NVIDIA CUDA | |
| 406 | case OsNVCL: // NVIDIA OpenCL | |
| 407 | case OsAMDHSA: // AMD HSA Runtime | |
| 408 | case OsPS4: | |
| 409 | case OsELFIAMCU: | |
| 410 | case OsTvOS: // Apple tvOS | |
| 411 | case OsWatchOS: // Apple watchOS | |
| 412 | case OsMesa3D: | |
| 413 | case OsContiki: | |
| 414 | return ZigLLVMGetOSTypeName(get_llvm_os_type(os_type)); | |
| 415 | } | |
| 416 | zig_unreachable(); | |
| 242 | 417 | } |
| 243 | 418 | |
| 244 | 419 | size_t target_environ_count(void) { |
| ... | ... | @@ -249,20 +424,22 @@ ZigLLVM_EnvironmentType get_target_environ(size_t index) { |
| 249 | 424 | } |
| 250 | 425 | |
| 251 | 426 | void get_native_target(ZigTarget *target) { |
| 427 | ZigLLVM_OSType os_type; | |
| 252 | 428 | ZigLLVMGetNativeTarget( |
| 253 | 429 | &target->arch.arch, |
| 254 | 430 | &target->arch.sub_arch, |
| 255 | 431 | &target->vendor, |
| 256 | &target->os, | |
| 432 | &os_type, | |
| 257 | 433 | &target->env_type, |
| 258 | 434 | &target->oformat); |
| 435 | target->os = get_zig_os_type(os_type); | |
| 259 | 436 | } |
| 260 | 437 | |
| 261 | 438 | void get_unknown_target(ZigTarget *target) { |
| 262 | 439 | target->arch.arch = ZigLLVM_UnknownArch; |
| 263 | 440 | target->arch.sub_arch = ZigLLVM_NoSubArch; |
| 264 | 441 | target->vendor = ZigLLVM_UnknownVendor; |
| 265 | target->os = ZigLLVM_UnknownOS; | |
| 442 | target->os = OsFreestanding; | |
| 266 | 443 | target->env_type = ZigLLVM_UnknownEnvironment; |
| 267 | 444 | target->oformat = ZigLLVM_UnknownObjectFormat; |
| 268 | 445 | } |
| ... | ... | @@ -289,9 +466,9 @@ int parse_target_arch(const char *str, ArchType *out_arch) { |
| 289 | 466 | return ErrorFileNotFound; |
| 290 | 467 | } |
| 291 | 468 | |
| 292 | int parse_target_os(const char *str, ZigLLVM_OSType *out_os) { | |
| 469 | int parse_target_os(const char *str, Os *out_os) { | |
| 293 | 470 | for (size_t i = 0; i < array_length(os_list); i += 1) { |
| 294 | ZigLLVM_OSType os = os_list[i]; | |
| 471 | Os os = os_list[i]; | |
| 295 | 472 | const char *os_name = get_target_os_name(os); |
| 296 | 473 | if (strcmp(os_name, str) == 0) { |
| 297 | 474 | *out_os = os; |
| ... | ... | @@ -328,15 +505,14 @@ void get_target_triple(Buf *triple, const ZigTarget *target) { |
| 328 | 505 | buf_resize(triple, 0); |
| 329 | 506 | buf_appendf(triple, "%s-%s-%s-%s", arch_name, |
| 330 | 507 | ZigLLVMGetVendorTypeName(target->vendor), |
| 331 | ZigLLVMGetOSTypeName(target->os), | |
| 508 | ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)), | |
| 332 | 509 | ZigLLVMGetEnvironmentTypeName(target->env_type)); |
| 333 | 510 | } |
| 334 | 511 | |
| 335 | 512 | static bool is_os_darwin(ZigTarget *target) { |
| 336 | 513 | switch (target->os) { |
| 337 | case ZigLLVM_Darwin: | |
| 338 | case ZigLLVM_IOS: | |
| 339 | case ZigLLVM_MacOSX: | |
| 514 | case OsMacOSX: | |
| 515 | case OsIOS: | |
| 340 | 516 | return true; |
| 341 | 517 | default: |
| 342 | 518 | return false; |
| ... | ... | @@ -357,7 +533,7 @@ void resolve_target_object_format(ZigTarget *target) { |
| 357 | 533 | case ZigLLVM_x86_64: |
| 358 | 534 | if (is_os_darwin(target)) { |
| 359 | 535 | target->oformat = ZigLLVM_MachO; |
| 360 | } else if (target->os == ZigLLVM_Win32) { | |
| 536 | } else if (target->os == OsWindows) { | |
| 361 | 537 | target->oformat = ZigLLVM_COFF; |
| 362 | 538 | } else { |
| 363 | 539 | target->oformat = ZigLLVM_ELF; |
| ... | ... | @@ -489,7 +665,7 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) { |
| 489 | 665 | |
| 490 | 666 | uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 491 | 667 | switch (target->os) { |
| 492 | case ZigLLVM_UnknownOS: | |
| 668 | case OsFreestanding: | |
| 493 | 669 | switch (id) { |
| 494 | 670 | case CIntTypeShort: |
| 495 | 671 | case CIntTypeUShort: |
| ... | ... | @@ -506,9 +682,9 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 506 | 682 | case CIntTypeCount: |
| 507 | 683 | zig_unreachable(); |
| 508 | 684 | } |
| 509 | case ZigLLVM_Linux: | |
| 510 | case ZigLLVM_Darwin: | |
| 511 | case ZigLLVM_MacOSX: | |
| 685 | case OsLinux: | |
| 686 | case OsMacOSX: | |
| 687 | case OsZen: | |
| 512 | 688 | switch (id) { |
| 513 | 689 | case CIntTypeShort: |
| 514 | 690 | case CIntTypeUShort: |
| ... | ... | @@ -525,7 +701,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 525 | 701 | case CIntTypeCount: |
| 526 | 702 | zig_unreachable(); |
| 527 | 703 | } |
| 528 | case ZigLLVM_Win32: | |
| 704 | case OsWindows: | |
| 529 | 705 | switch (id) { |
| 530 | 706 | case CIntTypeShort: |
| 531 | 707 | case CIntTypeUShort: |
| ... | ... | @@ -541,40 +717,40 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { |
| 541 | 717 | case CIntTypeCount: |
| 542 | 718 | zig_unreachable(); |
| 543 | 719 | } |
| 544 | case ZigLLVM_Ananas: | |
| 545 | case ZigLLVM_CloudABI: | |
| 546 | case ZigLLVM_DragonFly: | |
| 547 | case ZigLLVM_FreeBSD: | |
| 548 | case ZigLLVM_IOS: | |
| 549 | case ZigLLVM_KFreeBSD: | |
| 550 | case ZigLLVM_Lv2: | |
| 551 | case ZigLLVM_NetBSD: | |
| 552 | case ZigLLVM_OpenBSD: | |
| 553 | case ZigLLVM_Solaris: | |
| 554 | case ZigLLVM_Haiku: | |
| 555 | case ZigLLVM_Minix: | |
| 556 | case ZigLLVM_RTEMS: | |
| 557 | case ZigLLVM_NaCl: | |
| 558 | case ZigLLVM_CNK: | |
| 559 | case ZigLLVM_Bitrig: | |
| 560 | case ZigLLVM_AIX: | |
| 561 | case ZigLLVM_CUDA: | |
| 562 | case ZigLLVM_NVCL: | |
| 563 | case ZigLLVM_AMDHSA: | |
| 564 | case ZigLLVM_PS4: | |
| 565 | case ZigLLVM_ELFIAMCU: | |
| 566 | case ZigLLVM_TvOS: | |
| 567 | case ZigLLVM_WatchOS: | |
| 568 | case ZigLLVM_Mesa3D: | |
| 569 | case ZigLLVM_Fuchsia: | |
| 570 | case ZigLLVM_Contiki: | |
| 720 | case OsAnanas: | |
| 721 | case OsCloudABI: | |
| 722 | case OsDragonFly: | |
| 723 | case OsFreeBSD: | |
| 724 | case OsIOS: | |
| 725 | case OsKFreeBSD: | |
| 726 | case OsLv2: | |
| 727 | case OsNetBSD: | |
| 728 | case OsOpenBSD: | |
| 729 | case OsSolaris: | |
| 730 | case OsHaiku: | |
| 731 | case OsMinix: | |
| 732 | case OsRTEMS: | |
| 733 | case OsNaCl: | |
| 734 | case OsCNK: | |
| 735 | case OsBitrig: | |
| 736 | case OsAIX: | |
| 737 | case OsCUDA: | |
| 738 | case OsNVCL: | |
| 739 | case OsAMDHSA: | |
| 740 | case OsPS4: | |
| 741 | case OsELFIAMCU: | |
| 742 | case OsTvOS: | |
| 743 | case OsWatchOS: | |
| 744 | case OsMesa3D: | |
| 745 | case OsFuchsia: | |
| 746 | case OsContiki: | |
| 571 | 747 | zig_panic("TODO c type size in bits for this target"); |
| 572 | 748 | } |
| 573 | 749 | zig_unreachable(); |
| 574 | 750 | } |
| 575 | 751 | |
| 576 | 752 | const char *target_o_file_ext(ZigTarget *target) { |
| 577 | if (target->env_type == ZigLLVM_MSVC || target->os == ZigLLVM_Win32) { | |
| 753 | if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows) { | |
| 578 | 754 | return ".obj"; |
| 579 | 755 | } else { |
| 580 | 756 | return ".o"; |
| ... | ... | @@ -590,7 +766,7 @@ const char *target_llvm_ir_file_ext(ZigTarget *target) { |
| 590 | 766 | } |
| 591 | 767 | |
| 592 | 768 | const char *target_exe_file_ext(ZigTarget *target) { |
| 593 | if (target->os == ZigLLVM_Win32) { | |
| 769 | if (target->os == OsWindows) { | |
| 594 | 770 | return ".exe"; |
| 595 | 771 | } else { |
| 596 | 772 | return ""; |
| ... | ... | @@ -690,12 +866,12 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target |
| 690 | 866 | return true; |
| 691 | 867 | } |
| 692 | 868 | |
| 693 | if (guest_target->os == ZigLLVM_Win32 && host_target->os == ZigLLVM_Win32 && | |
| 869 | if (guest_target->os == OsWindows && host_target->os == OsWindows && | |
| 694 | 870 | host_target->arch.arch == ZigLLVM_x86_64 && guest_target->arch.arch == ZigLLVM_x86) |
| 695 | 871 | { |
| 696 | 872 | // 64-bit windows can run 32-bit programs |
| 697 | 873 | return true; |
| 698 | 874 | } |
| 699 | ||
| 875 | ||
| 700 | 876 | return false; |
| 701 | 877 | } |
src/target.hpp+39-4| ... | ... | @@ -17,10 +17,45 @@ struct ArchType { |
| 17 | 17 | ZigLLVM_SubArchType sub_arch; |
| 18 | 18 | }; |
| 19 | 19 | |
| 20 | enum Os { | |
| 21 | OsFreestanding, | |
| 22 | OsAnanas, | |
| 23 | OsCloudABI, | |
| 24 | OsDragonFly, | |
| 25 | OsFreeBSD, | |
| 26 | OsFuchsia, | |
| 27 | OsIOS, | |
| 28 | OsKFreeBSD, | |
| 29 | OsLinux, | |
| 30 | OsLv2, // PS3 | |
| 31 | OsMacOSX, | |
| 32 | OsNetBSD, | |
| 33 | OsOpenBSD, | |
| 34 | OsSolaris, | |
| 35 | OsWindows, | |
| 36 | OsHaiku, | |
| 37 | OsMinix, | |
| 38 | OsRTEMS, | |
| 39 | OsNaCl, // Native Client | |
| 40 | OsCNK, // BG/P Compute-Node Kernel | |
| 41 | OsBitrig, | |
| 42 | OsAIX, | |
| 43 | OsCUDA, // NVIDIA CUDA | |
| 44 | OsNVCL, // NVIDIA OpenCL | |
| 45 | OsAMDHSA, // AMD HSA Runtime | |
| 46 | OsPS4, | |
| 47 | OsELFIAMCU, | |
| 48 | OsTvOS, // Apple tvOS | |
| 49 | OsWatchOS, // Apple watchOS | |
| 50 | OsMesa3D, | |
| 51 | OsContiki, | |
| 52 | OsZen, | |
| 53 | }; | |
| 54 | ||
| 20 | 55 | struct ZigTarget { |
| 21 | 56 | ArchType arch; |
| 22 | 57 | ZigLLVM_VendorType vendor; |
| 23 | ZigLLVM_OSType os; | |
| 58 | Os os; | |
| 24 | 59 | ZigLLVM_EnvironmentType env_type; |
| 25 | 60 | ZigLLVM_ObjectFormatType oformat; |
| 26 | 61 | }; |
| ... | ... | @@ -46,8 +81,8 @@ size_t target_vendor_count(void); |
| 46 | 81 | ZigLLVM_VendorType get_target_vendor(size_t index); |
| 47 | 82 | |
| 48 | 83 | size_t target_os_count(void); |
| 49 | ZigLLVM_OSType get_target_os(size_t index); | |
| 50 | const char *get_target_os_name(ZigLLVM_OSType os_type); | |
| 84 | Os get_target_os(size_t index); | |
| 85 | const char *get_target_os_name(Os os_type); | |
| 51 | 86 | |
| 52 | 87 | size_t target_environ_count(void); |
| 53 | 88 | ZigLLVM_EnvironmentType get_target_environ(size_t index); |
| ... | ... | @@ -61,7 +96,7 @@ void get_native_target(ZigTarget *target); |
| 61 | 96 | void get_unknown_target(ZigTarget *target); |
| 62 | 97 | |
| 63 | 98 | int parse_target_arch(const char *str, ArchType *arch); |
| 64 | int parse_target_os(const char *str, ZigLLVM_OSType *os); | |
| 99 | int parse_target_os(const char *str, Os *os); | |
| 65 | 100 | int parse_target_environ(const char *str, ZigLLVM_EnvironmentType *env_type); |
| 66 | 101 | |
| 67 | 102 | void init_all_targets(void); |
src/tokenizer.cpp+4| ... | ... | @@ -111,6 +111,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 111 | 111 | {"and", TokenIdKeywordAnd}, |
| 112 | 112 | {"asm", TokenIdKeywordAsm}, |
| 113 | 113 | {"break", TokenIdKeywordBreak}, |
| 114 | {"catch", TokenIdKeywordCatch}, | |
| 114 | 115 | {"coldcc", TokenIdKeywordColdCC}, |
| 115 | 116 | {"comptime", TokenIdKeywordCompTime}, |
| 116 | 117 | {"const", TokenIdKeywordConst}, |
| ... | ... | @@ -141,6 +142,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 141 | 142 | {"test", TokenIdKeywordTest}, |
| 142 | 143 | {"this", TokenIdKeywordThis}, |
| 143 | 144 | {"true", TokenIdKeywordTrue}, |
| 145 | {"try", TokenIdKeywordTry}, | |
| 144 | 146 | {"undefined", TokenIdKeywordUndefined}, |
| 145 | 147 | {"union", TokenIdKeywordUnion}, |
| 146 | 148 | {"unreachable", TokenIdKeywordUnreachable}, |
| ... | ... | @@ -1511,6 +1513,7 @@ const char * token_name(TokenId id) { |
| 1511 | 1513 | case TokenIdKeywordAnd: return "and"; |
| 1512 | 1514 | case TokenIdKeywordAsm: return "asm"; |
| 1513 | 1515 | case TokenIdKeywordBreak: return "break"; |
| 1516 | case TokenIdKeywordCatch: return "catch"; | |
| 1514 | 1517 | case TokenIdKeywordColdCC: return "coldcc"; |
| 1515 | 1518 | case TokenIdKeywordCompTime: return "comptime"; |
| 1516 | 1519 | case TokenIdKeywordConst: return "const"; |
| ... | ... | @@ -1541,6 +1544,7 @@ const char * token_name(TokenId id) { |
| 1541 | 1544 | case TokenIdKeywordTest: return "test"; |
| 1542 | 1545 | case TokenIdKeywordThis: return "this"; |
| 1543 | 1546 | case TokenIdKeywordTrue: return "true"; |
| 1547 | case TokenIdKeywordTry: return "try"; | |
| 1544 | 1548 | case TokenIdKeywordUndefined: return "undefined"; |
| 1545 | 1549 | case TokenIdKeywordUnion: return "union"; |
| 1546 | 1550 | case TokenIdKeywordUnreachable: return "unreachable"; |
src/tokenizer.hpp+3-1| ... | ... | @@ -47,10 +47,10 @@ enum TokenId { |
| 47 | 47 | TokenIdFloatLiteral, |
| 48 | 48 | TokenIdIntLiteral, |
| 49 | 49 | TokenIdKeywordAlign, |
| 50 | TokenIdKeywordSection, | |
| 51 | 50 | TokenIdKeywordAnd, |
| 52 | 51 | TokenIdKeywordAsm, |
| 53 | 52 | TokenIdKeywordBreak, |
| 53 | TokenIdKeywordCatch, | |
| 54 | 54 | TokenIdKeywordColdCC, |
| 55 | 55 | TokenIdKeywordCompTime, |
| 56 | 56 | TokenIdKeywordConst, |
| ... | ... | @@ -74,12 +74,14 @@ enum TokenId { |
| 74 | 74 | TokenIdKeywordPacked, |
| 75 | 75 | TokenIdKeywordPub, |
| 76 | 76 | TokenIdKeywordReturn, |
| 77 | TokenIdKeywordSection, | |
| 77 | 78 | TokenIdKeywordStdcallCC, |
| 78 | 79 | TokenIdKeywordStruct, |
| 79 | 80 | TokenIdKeywordSwitch, |
| 80 | 81 | TokenIdKeywordTest, |
| 81 | 82 | TokenIdKeywordThis, |
| 82 | 83 | TokenIdKeywordTrue, |
| 84 | TokenIdKeywordTry, | |
| 83 | 85 | TokenIdKeywordUndefined, |
| 84 | 86 | TokenIdKeywordUnion, |
| 85 | 87 | TokenIdKeywordUnreachable, |
std/array_list.zig+5-5| ... | ... | @@ -60,18 +60,18 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | pub fn append(l: &Self, item: &const T) -> %void { |
| 63 | const new_item_ptr = %return l.addOne(); | |
| 63 | const new_item_ptr = try l.addOne(); | |
| 64 | 64 | *new_item_ptr = *item; |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void { |
| 68 | %return l.ensureCapacity(l.len + items.len); | |
| 68 | try l.ensureCapacity(l.len + items.len); | |
| 69 | 69 | mem.copy(T, l.items[l.len..], items); |
| 70 | 70 | l.len += items.len; |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | pub fn resize(l: &Self, new_len: usize) -> %void { |
| 74 | %return l.ensureCapacity(new_len); | |
| 74 | try l.ensureCapacity(new_len); | |
| 75 | 75 | l.len = new_len; |
| 76 | 76 | } |
| 77 | 77 | |
| ... | ... | @@ -87,12 +87,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{ |
| 87 | 87 | better_capacity += better_capacity / 2 + 8; |
| 88 | 88 | if (better_capacity >= new_capacity) break; |
| 89 | 89 | } |
| 90 | l.items = %return l.allocator.alignedRealloc(T, A, l.items, better_capacity); | |
| 90 | l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity); | |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | pub fn addOne(l: &Self) -> %&T { |
| 94 | 94 | const new_length = l.len + 1; |
| 95 | %return l.ensureCapacity(new_length); | |
| 95 | try l.ensureCapacity(new_length); | |
| 96 | 96 | const result = &l.items[l.len]; |
| 97 | 97 | l.len = new_length; |
| 98 | 98 | return result; |
std/base64.zig+35-35| ... | ... | @@ -379,37 +379,37 @@ test "base64" { |
| 379 | 379 | } |
| 380 | 380 | |
| 381 | 381 | fn testBase64() -> %void { |
| 382 | %return testAllApis("", ""); | |
| 383 | %return testAllApis("f", "Zg=="); | |
| 384 | %return testAllApis("fo", "Zm8="); | |
| 385 | %return testAllApis("foo", "Zm9v"); | |
| 386 | %return testAllApis("foob", "Zm9vYg=="); | |
| 387 | %return testAllApis("fooba", "Zm9vYmE="); | |
| 388 | %return testAllApis("foobar", "Zm9vYmFy"); | |
| 389 | ||
| 390 | %return testDecodeIgnoreSpace("", " "); | |
| 391 | %return testDecodeIgnoreSpace("f", "Z g= ="); | |
| 392 | %return testDecodeIgnoreSpace("fo", " Zm8="); | |
| 393 | %return testDecodeIgnoreSpace("foo", "Zm9v "); | |
| 394 | %return testDecodeIgnoreSpace("foob", "Zm9vYg = = "); | |
| 395 | %return testDecodeIgnoreSpace("fooba", "Zm9v YmE="); | |
| 396 | %return testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y "); | |
| 382 | try testAllApis("", ""); | |
| 383 | try testAllApis("f", "Zg=="); | |
| 384 | try testAllApis("fo", "Zm8="); | |
| 385 | try testAllApis("foo", "Zm9v"); | |
| 386 | try testAllApis("foob", "Zm9vYg=="); | |
| 387 | try testAllApis("fooba", "Zm9vYmE="); | |
| 388 | try testAllApis("foobar", "Zm9vYmFy"); | |
| 389 | ||
| 390 | try testDecodeIgnoreSpace("", " "); | |
| 391 | try testDecodeIgnoreSpace("f", "Z g= ="); | |
| 392 | try testDecodeIgnoreSpace("fo", " Zm8="); | |
| 393 | try testDecodeIgnoreSpace("foo", "Zm9v "); | |
| 394 | try testDecodeIgnoreSpace("foob", "Zm9vYg = = "); | |
| 395 | try testDecodeIgnoreSpace("fooba", "Zm9v YmE="); | |
| 396 | try testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y "); | |
| 397 | 397 | |
| 398 | 398 | // test getting some api errors |
| 399 | %return testError("A", error.InvalidPadding); | |
| 400 | %return testError("AA", error.InvalidPadding); | |
| 401 | %return testError("AAA", error.InvalidPadding); | |
| 402 | %return testError("A..A", error.InvalidCharacter); | |
| 403 | %return testError("AA=A", error.InvalidCharacter); | |
| 404 | %return testError("AA/=", error.InvalidPadding); | |
| 405 | %return testError("A/==", error.InvalidPadding); | |
| 406 | %return testError("A===", error.InvalidCharacter); | |
| 407 | %return testError("====", error.InvalidCharacter); | |
| 408 | ||
| 409 | %return testOutputTooSmallError("AA=="); | |
| 410 | %return testOutputTooSmallError("AAA="); | |
| 411 | %return testOutputTooSmallError("AAAA"); | |
| 412 | %return testOutputTooSmallError("AAAAAA=="); | |
| 399 | try testError("A", error.InvalidPadding); | |
| 400 | try testError("AA", error.InvalidPadding); | |
| 401 | try testError("AAA", error.InvalidPadding); | |
| 402 | try testError("A..A", error.InvalidCharacter); | |
| 403 | try testError("AA=A", error.InvalidCharacter); | |
| 404 | try testError("AA/=", error.InvalidPadding); | |
| 405 | try testError("A/==", error.InvalidPadding); | |
| 406 | try testError("A===", error.InvalidCharacter); | |
| 407 | try testError("====", error.InvalidCharacter); | |
| 408 | ||
| 409 | try testOutputTooSmallError("AA=="); | |
| 410 | try testOutputTooSmallError("AAA="); | |
| 411 | try testOutputTooSmallError("AAAA"); | |
| 412 | try testOutputTooSmallError("AAAAAA=="); | |
| 413 | 413 | } |
| 414 | 414 | |
| 415 | 415 | fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void { |
| ... | ... | @@ -424,8 +424,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v |
| 424 | 424 | // Base64Decoder |
| 425 | 425 | { |
| 426 | 426 | var buffer: [0x100]u8 = undefined; |
| 427 | var decoded = buffer[0..%return standard_decoder.calcSize(expected_encoded)]; | |
| 428 | %return standard_decoder.decode(decoded, expected_encoded); | |
| 427 | var decoded = buffer[0..try standard_decoder.calcSize(expected_encoded)]; | |
| 428 | try standard_decoder.decode(decoded, expected_encoded); | |
| 429 | 429 | assert(mem.eql(u8, decoded, expected_decoded)); |
| 430 | 430 | } |
| 431 | 431 | |
| ... | ... | @@ -434,8 +434,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v |
| 434 | 434 | const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init( |
| 435 | 435 | standard_alphabet_chars, standard_pad_char, ""); |
| 436 | 436 | var buffer: [0x100]u8 = undefined; |
| 437 | var decoded = buffer[0..%return Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)]; | |
| 438 | var written = %return standard_decoder_ignore_nothing.decode(decoded, expected_encoded); | |
| 437 | var decoded = buffer[0..try Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)]; | |
| 438 | var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded); | |
| 439 | 439 | assert(written <= decoded.len); |
| 440 | 440 | assert(mem.eql(u8, decoded[0..written], expected_decoded)); |
| 441 | 441 | } |
| ... | ... | @@ -453,8 +453,8 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> % |
| 453 | 453 | const standard_decoder_ignore_space = Base64DecoderWithIgnore.init( |
| 454 | 454 | standard_alphabet_chars, standard_pad_char, " "); |
| 455 | 455 | var buffer: [0x100]u8 = undefined; |
| 456 | var decoded = buffer[0..%return Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)]; | |
| 457 | var written = %return standard_decoder_ignore_space.decode(decoded, encoded); | |
| 456 | var decoded = buffer[0..try Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)]; | |
| 457 | var written = try standard_decoder_ignore_space.decode(decoded, encoded); | |
| 458 | 458 | assert(mem.eql(u8, decoded[0..written], expected_decoded)); |
| 459 | 459 | } |
| 460 | 460 |
std/buf_map.zig+6-6| ... | ... | @@ -29,16 +29,16 @@ pub const BufMap = struct { |
| 29 | 29 | |
| 30 | 30 | pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void { |
| 31 | 31 | if (self.hash_map.get(key)) |entry| { |
| 32 | const value_copy = %return self.copy(value); | |
| 32 | const value_copy = try self.copy(value); | |
| 33 | 33 | %defer self.free(value_copy); |
| 34 | _ = %return self.hash_map.put(key, value_copy); | |
| 34 | _ = try self.hash_map.put(key, value_copy); | |
| 35 | 35 | self.free(entry.value); |
| 36 | 36 | } else { |
| 37 | const key_copy = %return self.copy(key); | |
| 37 | const key_copy = try self.copy(key); | |
| 38 | 38 | %defer self.free(key_copy); |
| 39 | const value_copy = %return self.copy(value); | |
| 39 | const value_copy = try self.copy(value); | |
| 40 | 40 | %defer self.free(value_copy); |
| 41 | _ = %return self.hash_map.put(key_copy, value_copy); | |
| 41 | _ = try self.hash_map.put(key_copy, value_copy); | |
| 42 | 42 | } |
| 43 | 43 | } |
| 44 | 44 | |
| ... | ... | @@ -68,7 +68,7 @@ pub const BufMap = struct { |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | fn copy(self: &BufMap, value: []const u8) -> %[]const u8 { |
| 71 | const result = %return self.hash_map.allocator.alloc(u8, value.len); | |
| 71 | const result = try self.hash_map.allocator.alloc(u8, value.len); | |
| 72 | 72 | mem.copy(u8, result, value); |
| 73 | 73 | return result; |
| 74 | 74 | } |
std/buf_set.zig+3-3| ... | ... | @@ -26,9 +26,9 @@ pub const BufSet = struct { |
| 26 | 26 | |
| 27 | 27 | pub fn put(self: &BufSet, key: []const u8) -> %void { |
| 28 | 28 | if (self.hash_map.get(key) == null) { |
| 29 | const key_copy = %return self.copy(key); | |
| 29 | const key_copy = try self.copy(key); | |
| 30 | 30 | %defer self.free(key_copy); |
| 31 | _ = %return self.hash_map.put(key_copy, {}); | |
| 31 | _ = try self.hash_map.put(key_copy, {}); | |
| 32 | 32 | } |
| 33 | 33 | } |
| 34 | 34 | |
| ... | ... | @@ -56,7 +56,7 @@ pub const BufSet = struct { |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | fn copy(self: &BufSet, value: []const u8) -> %[]const u8 { |
| 59 | const result = %return self.hash_map.allocator.alloc(u8, value.len); | |
| 59 | const result = try self.hash_map.allocator.alloc(u8, value.len); | |
| 60 | 60 | mem.copy(u8, result, value); |
| 61 | 61 | return result; |
| 62 | 62 | } |
std/buffer.zig+6-6| ... | ... | @@ -13,7 +13,7 @@ pub const Buffer = struct { |
| 13 | 13 | |
| 14 | 14 | /// Must deinitialize with deinit. |
| 15 | 15 | pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer { |
| 16 | var self = %return initSize(allocator, m.len); | |
| 16 | var self = try initSize(allocator, m.len); | |
| 17 | 17 | mem.copy(u8, self.list.items, m); |
| 18 | 18 | return self; |
| 19 | 19 | } |
| ... | ... | @@ -21,7 +21,7 @@ pub const Buffer = struct { |
| 21 | 21 | /// Must deinitialize with deinit. |
| 22 | 22 | pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer { |
| 23 | 23 | var self = initNull(allocator); |
| 24 | %return self.resize(size); | |
| 24 | try self.resize(size); | |
| 25 | 25 | return self; |
| 26 | 26 | } |
| 27 | 27 | |
| ... | ... | @@ -81,7 +81,7 @@ pub const Buffer = struct { |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | pub fn resize(self: &Buffer, new_len: usize) -> %void { |
| 84 | %return self.list.resize(new_len + 1); | |
| 84 | try self.list.resize(new_len + 1); | |
| 85 | 85 | self.list.items[self.len()] = 0; |
| 86 | 86 | } |
| 87 | 87 | |
| ... | ... | @@ -95,7 +95,7 @@ pub const Buffer = struct { |
| 95 | 95 | |
| 96 | 96 | pub fn append(self: &Buffer, m: []const u8) -> %void { |
| 97 | 97 | const old_len = self.len(); |
| 98 | %return self.resize(old_len + m.len); | |
| 98 | try self.resize(old_len + m.len); | |
| 99 | 99 | mem.copy(u8, self.list.toSlice()[old_len..], m); |
| 100 | 100 | } |
| 101 | 101 | |
| ... | ... | @@ -113,7 +113,7 @@ pub const Buffer = struct { |
| 113 | 113 | pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void { |
| 114 | 114 | var prev_size: usize = self.len(); |
| 115 | 115 | const new_size = prev_size + count; |
| 116 | %return self.resize(new_size); | |
| 116 | try self.resize(new_size); | |
| 117 | 117 | |
| 118 | 118 | var i: usize = prev_size; |
| 119 | 119 | while (i < new_size) : (i += 1) { |
| ... | ... | @@ -138,7 +138,7 @@ pub const Buffer = struct { |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void { |
| 141 | %return self.resize(m.len); | |
| 141 | try self.resize(m.len); | |
| 142 | 142 | mem.copy(u8, self.list.toSlice(), m); |
| 143 | 143 | } |
| 144 | 144 |
std/build.zig+37-37| ... | ... | @@ -250,13 +250,13 @@ pub const Builder = struct { |
| 250 | 250 | %%wanted_steps.append(&self.default_step); |
| 251 | 251 | } else { |
| 252 | 252 | for (step_names) |step_name| { |
| 253 | const s = %return self.getTopLevelStepByName(step_name); | |
| 253 | const s = try self.getTopLevelStepByName(step_name); | |
| 254 | 254 | %%wanted_steps.append(s); |
| 255 | 255 | } |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | for (wanted_steps.toSliceConst()) |s| { |
| 259 | %return self.makeOneStep(s); | |
| 259 | try self.makeOneStep(s); | |
| 260 | 260 | } |
| 261 | 261 | } |
| 262 | 262 | |
| ... | ... | @@ -300,7 +300,7 @@ pub const Builder = struct { |
| 300 | 300 | s.loop_flag = true; |
| 301 | 301 | |
| 302 | 302 | for (s.dependencies.toSlice()) |dep| { |
| 303 | self.makeOneStep(dep) %% |err| { | |
| 303 | self.makeOneStep(dep) catch |err| { | |
| 304 | 304 | if (err == error.DependencyLoopDetected) { |
| 305 | 305 | warn(" {}\n", s.name); |
| 306 | 306 | } |
| ... | ... | @@ -310,7 +310,7 @@ pub const Builder = struct { |
| 310 | 310 | |
| 311 | 311 | s.loop_flag = false; |
| 312 | 312 | |
| 313 | %return s.make(); | |
| 313 | try s.make(); | |
| 314 | 314 | } |
| 315 | 315 | |
| 316 | 316 | fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step { |
| ... | ... | @@ -573,7 +573,7 @@ pub const Builder = struct { |
| 573 | 573 | child.cwd = cwd; |
| 574 | 574 | child.env_map = env_map; |
| 575 | 575 | |
| 576 | const term = child.spawnAndWait() %% |err| { | |
| 576 | const term = child.spawnAndWait() catch |err| { | |
| 577 | 577 | warn("Unable to spawn {}: {}\n", argv[0], @errorName(err)); |
| 578 | 578 | return err; |
| 579 | 579 | }; |
| ... | ... | @@ -596,7 +596,7 @@ pub const Builder = struct { |
| 596 | 596 | } |
| 597 | 597 | |
| 598 | 598 | pub fn makePath(self: &Builder, path: []const u8) -> %void { |
| 599 | os.makePath(self.allocator, self.pathFromRoot(path)) %% |err| { | |
| 599 | os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| { | |
| 600 | 600 | warn("Unable to create path {}: {}\n", path, @errorName(err)); |
| 601 | 601 | return err; |
| 602 | 602 | }; |
| ... | ... | @@ -641,11 +641,11 @@ pub const Builder = struct { |
| 641 | 641 | |
| 642 | 642 | const dirname = os.path.dirname(dest_path); |
| 643 | 643 | const abs_source_path = self.pathFromRoot(source_path); |
| 644 | os.makePath(self.allocator, dirname) %% |err| { | |
| 644 | os.makePath(self.allocator, dirname) catch |err| { | |
| 645 | 645 | warn("Unable to create path {}: {}\n", dirname, @errorName(err)); |
| 646 | 646 | return err; |
| 647 | 647 | }; |
| 648 | os.copyFileMode(self.allocator, abs_source_path, dest_path, mode) %% |err| { | |
| 648 | os.copyFileMode(self.allocator, abs_source_path, dest_path, mode) catch |err| { | |
| 649 | 649 | warn("Unable to copy {} to {}: {}\n", abs_source_path, dest_path, @errorName(err)); |
| 650 | 650 | return err; |
| 651 | 651 | }; |
| ... | ... | @@ -663,7 +663,7 @@ pub const Builder = struct { |
| 663 | 663 | if (builtin.environ == builtin.Environ.msvc) { |
| 664 | 664 | return "cl.exe"; |
| 665 | 665 | } else { |
| 666 | return os.getEnvVarOwned(self.allocator, "CC") %% |err| | |
| 666 | return os.getEnvVarOwned(self.allocator, "CC") catch |err| | |
| 667 | 667 | if (err == error.EnvironmentVariableNotFound) |
| 668 | 668 | ([]const u8)("cc") |
| 669 | 669 | else |
| ... | ... | @@ -680,7 +680,7 @@ pub const Builder = struct { |
| 680 | 680 | if (os.path.isAbsolute(name)) { |
| 681 | 681 | return name; |
| 682 | 682 | } |
| 683 | const full_path = %return os.path.join(self.allocator, search_prefix, "bin", | |
| 683 | const full_path = try os.path.join(self.allocator, search_prefix, "bin", | |
| 684 | 684 | self.fmt("{}{}", name, exe_extension)); |
| 685 | 685 | if (os.path.real(self.allocator, full_path)) |real_path| { |
| 686 | 686 | return real_path; |
| ... | ... | @@ -696,7 +696,7 @@ pub const Builder = struct { |
| 696 | 696 | } |
| 697 | 697 | var it = mem.split(PATH, []u8{os.path.delimiter}); |
| 698 | 698 | while (it.next()) |path| { |
| 699 | const full_path = %return os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); | |
| 699 | const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); | |
| 700 | 700 | if (os.path.real(self.allocator, full_path)) |real_path| { |
| 701 | 701 | return real_path; |
| 702 | 702 | } else |_| { |
| ... | ... | @@ -710,7 +710,7 @@ pub const Builder = struct { |
| 710 | 710 | return name; |
| 711 | 711 | } |
| 712 | 712 | for (paths) |path| { |
| 713 | const full_path = %return os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); | |
| 713 | const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension)); | |
| 714 | 714 | if (os.path.real(self.allocator, full_path)) |real_path| { |
| 715 | 715 | return real_path; |
| 716 | 716 | } else |_| { |
| ... | ... | @@ -723,7 +723,7 @@ pub const Builder = struct { |
| 723 | 723 | |
| 724 | 724 | pub fn exec(self: &Builder, argv: []const []const u8) -> []u8 { |
| 725 | 725 | const max_output_size = 100 * 1024; |
| 726 | const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) %% |err| { | |
| 726 | const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) catch |err| { | |
| 727 | 727 | std.debug.panic("Unable to spawn {}: {}", argv[0], @errorName(err)); |
| 728 | 728 | }; |
| 729 | 729 | switch (result.term) { |
| ... | ... | @@ -800,7 +800,7 @@ const Target = union(enum) { |
| 800 | 800 | |
| 801 | 801 | pub fn isDarwin(self: &const Target) -> bool { |
| 802 | 802 | return switch (self.getOs()) { |
| 803 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => true, | |
| 803 | builtin.Os.ios, builtin.Os.macosx => true, | |
| 804 | 804 | else => false, |
| 805 | 805 | }; |
| 806 | 806 | } |
| ... | ... | @@ -1011,7 +1011,7 @@ pub const LibExeObjStep = struct { |
| 1011 | 1011 | self.out_filename = self.builder.fmt("lib{}.a", self.name); |
| 1012 | 1012 | } else { |
| 1013 | 1013 | switch (self.target.getOs()) { |
| 1014 | builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => { | |
| 1014 | builtin.Os.ios, builtin.Os.macosx => { | |
| 1015 | 1015 | self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", |
| 1016 | 1016 | self.name, self.version.major, self.version.minor, self.version.patch); |
| 1017 | 1017 | self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major); |
| ... | ... | @@ -1345,10 +1345,10 @@ pub const LibExeObjStep = struct { |
| 1345 | 1345 | } |
| 1346 | 1346 | } |
| 1347 | 1347 | |
| 1348 | %return builder.spawnChild(zig_args.toSliceConst()); | |
| 1348 | try builder.spawnChild(zig_args.toSliceConst()); | |
| 1349 | 1349 | |
| 1350 | 1350 | if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) { |
| 1351 | %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | |
| 1351 | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | |
| 1352 | 1352 | self.name_only_filename); |
| 1353 | 1353 | } |
| 1354 | 1354 | } |
| ... | ... | @@ -1423,7 +1423,7 @@ pub const LibExeObjStep = struct { |
| 1423 | 1423 | |
| 1424 | 1424 | self.appendCompileFlags(&cc_args); |
| 1425 | 1425 | |
| 1426 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1426 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1427 | 1427 | }, |
| 1428 | 1428 | Kind.Lib => { |
| 1429 | 1429 | for (self.source_files.toSliceConst()) |source_file| { |
| ... | ... | @@ -1440,14 +1440,14 @@ pub const LibExeObjStep = struct { |
| 1440 | 1440 | |
| 1441 | 1441 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file); |
| 1442 | 1442 | const cache_o_dir = os.path.dirname(cache_o_src); |
| 1443 | %return builder.makePath(cache_o_dir); | |
| 1443 | try builder.makePath(cache_o_dir); | |
| 1444 | 1444 | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); |
| 1445 | 1445 | %%cc_args.append("-o"); |
| 1446 | 1446 | %%cc_args.append(builder.pathFromRoot(cache_o_file)); |
| 1447 | 1447 | |
| 1448 | 1448 | self.appendCompileFlags(&cc_args); |
| 1449 | 1449 | |
| 1450 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1450 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1451 | 1451 | |
| 1452 | 1452 | %%self.object_files.append(cache_o_file); |
| 1453 | 1453 | } |
| ... | ... | @@ -1466,14 +1466,14 @@ pub const LibExeObjStep = struct { |
| 1466 | 1466 | %%cc_args.append(builder.pathFromRoot(object_file)); |
| 1467 | 1467 | } |
| 1468 | 1468 | |
| 1469 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1469 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1470 | 1470 | |
| 1471 | 1471 | // ranlib |
| 1472 | 1472 | %%cc_args.resize(0); |
| 1473 | 1473 | %%cc_args.append("ranlib"); |
| 1474 | 1474 | %%cc_args.append(output_path); |
| 1475 | 1475 | |
| 1476 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1476 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1477 | 1477 | } else { |
| 1478 | 1478 | %%cc_args.resize(0); |
| 1479 | 1479 | %%cc_args.append(cc); |
| ... | ... | @@ -1537,10 +1537,10 @@ pub const LibExeObjStep = struct { |
| 1537 | 1537 | } |
| 1538 | 1538 | } |
| 1539 | 1539 | |
| 1540 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1540 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1541 | 1541 | |
| 1542 | 1542 | if (self.target.wantSharedLibSymLinks()) { |
| 1543 | %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | |
| 1543 | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | |
| 1544 | 1544 | self.name_only_filename); |
| 1545 | 1545 | } |
| 1546 | 1546 | } |
| ... | ... | @@ -1556,7 +1556,7 @@ pub const LibExeObjStep = struct { |
| 1556 | 1556 | |
| 1557 | 1557 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file); |
| 1558 | 1558 | const cache_o_dir = os.path.dirname(cache_o_src); |
| 1559 | %return builder.makePath(cache_o_dir); | |
| 1559 | try builder.makePath(cache_o_dir); | |
| 1560 | 1560 | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); |
| 1561 | 1561 | %%cc_args.append("-o"); |
| 1562 | 1562 | %%cc_args.append(builder.pathFromRoot(cache_o_file)); |
| ... | ... | @@ -1570,7 +1570,7 @@ pub const LibExeObjStep = struct { |
| 1570 | 1570 | %%cc_args.append(builder.pathFromRoot(dir)); |
| 1571 | 1571 | } |
| 1572 | 1572 | |
| 1573 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1573 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1574 | 1574 | |
| 1575 | 1575 | %%self.object_files.append(cache_o_file); |
| 1576 | 1576 | } |
| ... | ... | @@ -1619,7 +1619,7 @@ pub const LibExeObjStep = struct { |
| 1619 | 1619 | } |
| 1620 | 1620 | } |
| 1621 | 1621 | |
| 1622 | %return builder.spawnChild(cc_args.toSliceConst()); | |
| 1622 | try builder.spawnChild(cc_args.toSliceConst()); | |
| 1623 | 1623 | }, |
| 1624 | 1624 | } |
| 1625 | 1625 | } |
| ... | ... | @@ -1770,7 +1770,7 @@ pub const TestStep = struct { |
| 1770 | 1770 | %%zig_args.append(lib_path); |
| 1771 | 1771 | } |
| 1772 | 1772 | |
| 1773 | %return builder.spawnChild(zig_args.toSliceConst()); | |
| 1773 | try builder.spawnChild(zig_args.toSliceConst()); | |
| 1774 | 1774 | } |
| 1775 | 1775 | }; |
| 1776 | 1776 | |
| ... | ... | @@ -1847,9 +1847,9 @@ const InstallArtifactStep = struct { |
| 1847 | 1847 | LibExeObjStep.Kind.Exe => usize(0o755), |
| 1848 | 1848 | LibExeObjStep.Kind.Lib => if (self.artifact.static) usize(0o666) else usize(0o755), |
| 1849 | 1849 | }; |
| 1850 | %return builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode); | |
| 1850 | try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode); | |
| 1851 | 1851 | if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) { |
| 1852 | %return doAtomicSymLinks(builder.allocator, self.dest_file, | |
| 1852 | try doAtomicSymLinks(builder.allocator, self.dest_file, | |
| 1853 | 1853 | self.artifact.major_only_filename, self.artifact.name_only_filename); |
| 1854 | 1854 | } |
| 1855 | 1855 | } |
| ... | ... | @@ -1872,7 +1872,7 @@ pub const InstallFileStep = struct { |
| 1872 | 1872 | |
| 1873 | 1873 | fn make(step: &Step) -> %void { |
| 1874 | 1874 | const self = @fieldParentPtr(InstallFileStep, "step", step); |
| 1875 | %return self.builder.copyFile(self.src_path, self.dest_path); | |
| 1875 | try self.builder.copyFile(self.src_path, self.dest_path); | |
| 1876 | 1876 | } |
| 1877 | 1877 | }; |
| 1878 | 1878 | |
| ... | ... | @@ -1895,11 +1895,11 @@ pub const WriteFileStep = struct { |
| 1895 | 1895 | const self = @fieldParentPtr(WriteFileStep, "step", step); |
| 1896 | 1896 | const full_path = self.builder.pathFromRoot(self.file_path); |
| 1897 | 1897 | const full_path_dir = os.path.dirname(full_path); |
| 1898 | os.makePath(self.builder.allocator, full_path_dir) %% |err| { | |
| 1898 | os.makePath(self.builder.allocator, full_path_dir) catch |err| { | |
| 1899 | 1899 | warn("unable to make path {}: {}\n", full_path_dir, @errorName(err)); |
| 1900 | 1900 | return err; |
| 1901 | 1901 | }; |
| 1902 | io.writeFile(full_path, self.data, self.builder.allocator) %% |err| { | |
| 1902 | io.writeFile(full_path, self.data, self.builder.allocator) catch |err| { | |
| 1903 | 1903 | warn("unable to write {}: {}\n", full_path, @errorName(err)); |
| 1904 | 1904 | return err; |
| 1905 | 1905 | }; |
| ... | ... | @@ -1942,7 +1942,7 @@ pub const RemoveDirStep = struct { |
| 1942 | 1942 | const self = @fieldParentPtr(RemoveDirStep, "step", step); |
| 1943 | 1943 | |
| 1944 | 1944 | const full_path = self.builder.pathFromRoot(self.dir_path); |
| 1945 | os.deleteTree(self.builder.allocator, full_path) %% |err| { | |
| 1945 | os.deleteTree(self.builder.allocator, full_path) catch |err| { | |
| 1946 | 1946 | warn("Unable to remove {}: {}\n", full_path, @errorName(err)); |
| 1947 | 1947 | return err; |
| 1948 | 1948 | }; |
| ... | ... | @@ -1973,7 +1973,7 @@ pub const Step = struct { |
| 1973 | 1973 | if (self.done_flag) |
| 1974 | 1974 | return; |
| 1975 | 1975 | |
| 1976 | %return self.makeFn(self); | |
| 1976 | try self.makeFn(self); | |
| 1977 | 1977 | self.done_flag = true; |
| 1978 | 1978 | } |
| 1979 | 1979 | |
| ... | ... | @@ -1991,13 +1991,13 @@ fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_maj |
| 1991 | 1991 | const out_basename = os.path.basename(output_path); |
| 1992 | 1992 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 |
| 1993 | 1993 | const major_only_path = %%os.path.join(allocator, out_dir, filename_major_only); |
| 1994 | os.atomicSymLink(allocator, out_basename, major_only_path) %% |err| { | |
| 1994 | os.atomicSymLink(allocator, out_basename, major_only_path) catch |err| { | |
| 1995 | 1995 | warn("Unable to symlink {} -> {}\n", major_only_path, out_basename); |
| 1996 | 1996 | return err; |
| 1997 | 1997 | }; |
| 1998 | 1998 | // sym link for libfoo.so to libfoo.so.1 |
| 1999 | 1999 | const name_only_path = %%os.path.join(allocator, out_dir, filename_name_only); |
| 2000 | os.atomicSymLink(allocator, filename_major_only, name_only_path) %% |err| { | |
| 2000 | os.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| { | |
| 2001 | 2001 | warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only); |
| 2002 | 2002 | return err; |
| 2003 | 2003 | }; |
std/c/index.zig+1-1| ... | ... | @@ -4,7 +4,7 @@ const Os = builtin.Os; |
| 4 | 4 | pub use switch(builtin.os) { |
| 5 | 5 | Os.linux => @import("linux.zig"), |
| 6 | 6 | Os.windows => @import("windows.zig"), |
| 7 | Os.darwin, Os.macosx, Os.ios => @import("darwin.zig"), | |
| 7 | Os.macosx, Os.ios => @import("darwin.zig"), | |
| 8 | 8 | else => empty_import, |
| 9 | 9 | }; |
| 10 | 10 | const empty_import = @import("../empty.zig"); |
std/cstr.zig+2-2| ... | ... | @@ -43,7 +43,7 @@ fn testCStrFnsImpl() { |
| 43 | 43 | /// have a null byte after it. |
| 44 | 44 | /// Caller owns the returned memory. |
| 45 | 45 | pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 { |
| 46 | const result = %return allocator.alloc(u8, slice.len + 1); | |
| 46 | const result = try allocator.alloc(u8, slice.len + 1); | |
| 47 | 47 | mem.copy(u8, result, slice); |
| 48 | 48 | result[slice.len] = 0; |
| 49 | 49 | return result; |
| ... | ... | @@ -70,7 +70,7 @@ pub const NullTerminated2DArray = struct { |
| 70 | 70 | const index_size = @sizeOf(usize) * new_len; // size of the ptrs |
| 71 | 71 | byte_count += index_size; |
| 72 | 72 | |
| 73 | const buf = %return allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count); | |
| 73 | const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count); | |
| 74 | 74 | %defer allocator.free(buf); |
| 75 | 75 | |
| 76 | 76 | var write_index = index_size; |
std/debug/failing_allocator.zig+2-2| ... | ... | @@ -33,7 +33,7 @@ pub const FailingAllocator = struct { |
| 33 | 33 | if (self.index == self.fail_index) { |
| 34 | 34 | return error.OutOfMemory; |
| 35 | 35 | } |
| 36 | const result = %return self.internal_allocator.allocFn(self.internal_allocator, n, alignment); | |
| 36 | const result = try self.internal_allocator.allocFn(self.internal_allocator, n, alignment); | |
| 37 | 37 | self.allocated_bytes += result.len; |
| 38 | 38 | self.index += 1; |
| 39 | 39 | return result; |
| ... | ... | @@ -48,7 +48,7 @@ pub const FailingAllocator = struct { |
| 48 | 48 | if (self.index == self.fail_index) { |
| 49 | 49 | return error.OutOfMemory; |
| 50 | 50 | } |
| 51 | const result = %return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment); | |
| 51 | const result = try self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment); | |
| 52 | 52 | self.allocated_bytes += new_size - old_mem.len; |
| 53 | 53 | self.deallocations += 1; |
| 54 | 54 | self.index += 1; |
std/debug/index.zig+133-133| ... | ... | @@ -22,14 +22,14 @@ var stderr_file: io.File = undefined; |
| 22 | 22 | var stderr_file_out_stream: io.FileOutStream = undefined; |
| 23 | 23 | var stderr_stream: ?&io.OutStream = null; |
| 24 | 24 | pub fn warn(comptime fmt: []const u8, args: ...) { |
| 25 | const stderr = getStderrStream() %% return; | |
| 26 | stderr.print(fmt, args) %% return; | |
| 25 | const stderr = getStderrStream() catch return; | |
| 26 | stderr.print(fmt, args) catch return; | |
| 27 | 27 | } |
| 28 | 28 | fn getStderrStream() -> %&io.OutStream { |
| 29 | 29 | if (stderr_stream) |st| { |
| 30 | 30 | return st; |
| 31 | 31 | } else { |
| 32 | stderr_file = %return io.getStdErr(); | |
| 32 | stderr_file = try io.getStdErr(); | |
| 33 | 33 | stderr_file_out_stream = io.FileOutStream.init(&stderr_file); |
| 34 | 34 | const st = &stderr_file_out_stream.stream; |
| 35 | 35 | stderr_stream = st; |
| ... | ... | @@ -39,8 +39,8 @@ fn getStderrStream() -> %&io.OutStream { |
| 39 | 39 | |
| 40 | 40 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. |
| 41 | 41 | pub fn dumpStackTrace() { |
| 42 | const stderr = getStderrStream() %% return; | |
| 43 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% return; | |
| 42 | const stderr = getStderrStream() catch return; | |
| 43 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) catch return; | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | /// This function invokes undefined behavior when `ok` is `false`. |
| ... | ... | @@ -86,9 +86,9 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn { |
| 86 | 86 | panicking = true; |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | const stderr = getStderrStream() %% os.abort(); | |
| 90 | stderr.print(format ++ "\n", args) %% os.abort(); | |
| 91 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% os.abort(); | |
| 89 | const stderr = getStderrStream() catch os.abort(); | |
| 90 | stderr.print(format ++ "\n", args) catch os.abort(); | |
| 91 | writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) catch os.abort(); | |
| 92 | 92 | |
| 93 | 93 | os.abort(); |
| 94 | 94 | } |
| ... | ... | @@ -118,18 +118,18 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 118 | 118 | .compile_unit_list = ArrayList(CompileUnit).init(allocator), |
| 119 | 119 | }; |
| 120 | 120 | const st = &stack_trace; |
| 121 | st.self_exe_file = %return os.openSelfExe(); | |
| 121 | st.self_exe_file = try os.openSelfExe(); | |
| 122 | 122 | defer st.self_exe_file.close(); |
| 123 | 123 | |
| 124 | %return st.elf.openFile(allocator, &st.self_exe_file); | |
| 124 | try st.elf.openFile(allocator, &st.self_exe_file); | |
| 125 | 125 | defer st.elf.close(); |
| 126 | 126 | |
| 127 | st.debug_info = (%return st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo; | |
| 128 | st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo; | |
| 129 | st.debug_str = (%return st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo; | |
| 130 | st.debug_line = (%return st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo; | |
| 131 | st.debug_ranges = (%return st.elf.findSection(".debug_ranges")); | |
| 132 | %return scanAllCompileUnits(st); | |
| 127 | st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo; | |
| 128 | st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo; | |
| 129 | st.debug_str = (try st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo; | |
| 130 | st.debug_line = (try st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo; | |
| 131 | st.debug_ranges = (try st.elf.findSection(".debug_ranges")); | |
| 132 | try scanAllCompileUnits(st); | |
| 133 | 133 | |
| 134 | 134 | var ignored_count: usize = 0; |
| 135 | 135 | |
| ... | ... | @@ -146,26 +146,26 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 146 | 146 | // at compile time. I'll call it issue #313 |
| 147 | 147 | const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}"; |
| 148 | 148 | |
| 149 | const compile_unit = findCompileUnit(st, return_address) %% { | |
| 150 | %return out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", | |
| 149 | const compile_unit = findCompileUnit(st, return_address) catch { | |
| 150 | try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", | |
| 151 | 151 | return_address); |
| 152 | 152 | continue; |
| 153 | 153 | }; |
| 154 | const compile_unit_name = %return compile_unit.die.getAttrString(st, DW.AT_name); | |
| 154 | const compile_unit_name = try compile_unit.die.getAttrString(st, DW.AT_name); | |
| 155 | 155 | if (getLineNumberInfo(st, compile_unit, usize(return_address) - 1)) |line_info| { |
| 156 | 156 | defer line_info.deinit(); |
| 157 | %return out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ | |
| 157 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ | |
| 158 | 158 | DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", |
| 159 | 159 | line_info.file_name, line_info.line, line_info.column, |
| 160 | 160 | return_address, compile_unit_name); |
| 161 | 161 | if (printLineFromFile(st.allocator(), out_stream, line_info)) { |
| 162 | 162 | if (line_info.column == 0) { |
| 163 | %return out_stream.write("\n"); | |
| 163 | try out_stream.write("\n"); | |
| 164 | 164 | } else { |
| 165 | 165 | {var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) { |
| 166 | %return out_stream.writeByte(' '); | |
| 166 | try out_stream.writeByte(' '); | |
| 167 | 167 | }} |
| 168 | %return out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | |
| 168 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | |
| 169 | 169 | } |
| 170 | 170 | } else |err| switch (err) { |
| 171 | 171 | error.EndOfFile, error.PathNotFound => {}, |
| ... | ... | @@ -173,7 +173,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 173 | 173 | } |
| 174 | 174 | } else |err| switch (err) { |
| 175 | 175 | error.MissingDebugInfo, error.InvalidDebugInfo => { |
| 176 | %return out_stream.print(ptr_hex ++ " in ??? ({})\n", | |
| 176 | try out_stream.print(ptr_hex ++ " in ??? ({})\n", | |
| 177 | 177 | return_address, compile_unit_name); |
| 178 | 178 | }, |
| 179 | 179 | else => return err, |
| ... | ... | @@ -181,22 +181,22 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty |
| 181 | 181 | } |
| 182 | 182 | }, |
| 183 | 183 | builtin.ObjectFormat.coff => { |
| 184 | %return out_stream.write("(stack trace unavailable for COFF object format)\n"); | |
| 184 | try out_stream.write("(stack trace unavailable for COFF object format)\n"); | |
| 185 | 185 | }, |
| 186 | 186 | builtin.ObjectFormat.macho => { |
| 187 | %return out_stream.write("(stack trace unavailable for Mach-O object format)\n"); | |
| 187 | try out_stream.write("(stack trace unavailable for Mach-O object format)\n"); | |
| 188 | 188 | }, |
| 189 | 189 | builtin.ObjectFormat.wasm => { |
| 190 | %return out_stream.write("(stack trace unavailable for WASM object format)\n"); | |
| 190 | try out_stream.write("(stack trace unavailable for WASM object format)\n"); | |
| 191 | 191 | }, |
| 192 | 192 | builtin.ObjectFormat.unknown => { |
| 193 | %return out_stream.write("(stack trace unavailable for unknown object format)\n"); | |
| 193 | try out_stream.write("(stack trace unavailable for unknown object format)\n"); | |
| 194 | 194 | }, |
| 195 | 195 | } |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | 198 | fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) -> %void { |
| 199 | var f = %return io.File.openRead(line_info.file_name, allocator); | |
| 199 | var f = try io.File.openRead(line_info.file_name, allocator); | |
| 200 | 200 | defer f.close(); |
| 201 | 201 | // TODO fstat and make sure that the file has the correct size |
| 202 | 202 | |
| ... | ... | @@ -205,12 +205,12 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_ |
| 205 | 205 | var column: usize = 1; |
| 206 | 206 | var abs_index: usize = 0; |
| 207 | 207 | while (true) { |
| 208 | const amt_read = %return f.read(buf[0..]); | |
| 208 | const amt_read = try f.read(buf[0..]); | |
| 209 | 209 | const slice = buf[0..amt_read]; |
| 210 | 210 | |
| 211 | 211 | for (slice) |byte| { |
| 212 | 212 | if (line == line_info.line) { |
| 213 | %return out_stream.writeByte(byte); | |
| 213 | try out_stream.writeByte(byte); | |
| 214 | 214 | if (byte == '\n') { |
| 215 | 215 | return; |
| 216 | 216 | } |
| ... | ... | @@ -437,7 +437,7 @@ const LineNumberProgram = struct { |
| 437 | 437 | const dir_name = if (file_entry.dir_index >= self.include_dirs.len) { |
| 438 | 438 | return error.InvalidDebugInfo; |
| 439 | 439 | } else self.include_dirs[file_entry.dir_index]; |
| 440 | const file_name = %return os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); | |
| 440 | const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); | |
| 441 | 441 | %defer self.file_entries.allocator.free(file_name); |
| 442 | 442 | return LineInfo { |
| 443 | 443 | .line = if (self.prev_line >= 0) usize(self.prev_line) else 0, |
| ... | ... | @@ -461,73 +461,73 @@ const LineNumberProgram = struct { |
| 461 | 461 | fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 { |
| 462 | 462 | var buf = ArrayList(u8).init(allocator); |
| 463 | 463 | while (true) { |
| 464 | const byte = %return in_stream.readByte(); | |
| 464 | const byte = try in_stream.readByte(); | |
| 465 | 465 | if (byte == 0) |
| 466 | 466 | break; |
| 467 | %return buf.append(byte); | |
| 467 | try buf.append(byte); | |
| 468 | 468 | } |
| 469 | 469 | return buf.toSlice(); |
| 470 | 470 | } |
| 471 | 471 | |
| 472 | 472 | fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 { |
| 473 | 473 | const pos = st.debug_str.offset + offset; |
| 474 | %return st.self_exe_file.seekTo(pos); | |
| 474 | try st.self_exe_file.seekTo(pos); | |
| 475 | 475 | return st.readString(); |
| 476 | 476 | } |
| 477 | 477 | |
| 478 | 478 | fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %[]u8 { |
| 479 | const buf = %return global_allocator.alloc(u8, size); | |
| 479 | const buf = try global_allocator.alloc(u8, size); | |
| 480 | 480 | %defer global_allocator.free(buf); |
| 481 | if ((%return in_stream.read(buf)) < size) return error.EndOfFile; | |
| 481 | if ((try in_stream.read(buf)) < size) return error.EndOfFile; | |
| 482 | 482 | return buf; |
| 483 | 483 | } |
| 484 | 484 | |
| 485 | 485 | fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { |
| 486 | const buf = %return readAllocBytes(allocator, in_stream, size); | |
| 486 | const buf = try readAllocBytes(allocator, in_stream, size); | |
| 487 | 487 | return FormValue { .Block = buf }; |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | 490 | fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { |
| 491 | const block_len = %return in_stream.readVarInt(builtin.Endian.Little, usize, size); | |
| 491 | const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size); | |
| 492 | 492 | return parseFormValueBlockLen(allocator, in_stream, block_len); |
| 493 | 493 | } |
| 494 | 494 | |
| 495 | 495 | fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue { |
| 496 | 496 | return FormValue { .Const = Constant { |
| 497 | 497 | .signed = signed, |
| 498 | .payload = %return readAllocBytes(allocator, in_stream, size), | |
| 498 | .payload = try readAllocBytes(allocator, in_stream, size), | |
| 499 | 499 | }}; |
| 500 | 500 | } |
| 501 | 501 | |
| 502 | 502 | fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 { |
| 503 | return if (is_64) %return in_stream.readIntLe(u64) | |
| 504 | else u64(%return in_stream.readIntLe(u32)) ; | |
| 503 | return if (is_64) try in_stream.readIntLe(u64) | |
| 504 | else u64(try in_stream.readIntLe(u32)) ; | |
| 505 | 505 | } |
| 506 | 506 | |
| 507 | 507 | fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 { |
| 508 | return if (@sizeOf(usize) == 4) u64(%return in_stream.readIntLe(u32)) | |
| 509 | else if (@sizeOf(usize) == 8) %return in_stream.readIntLe(u64) | |
| 508 | return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32)) | |
| 509 | else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64) | |
| 510 | 510 | else unreachable; |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | 513 | fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue { |
| 514 | const buf = %return readAllocBytes(allocator, in_stream, size); | |
| 514 | const buf = try readAllocBytes(allocator, in_stream, size); | |
| 515 | 515 | return FormValue { .Ref = buf }; |
| 516 | 516 | } |
| 517 | 517 | |
| 518 | 518 | fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue { |
| 519 | const block_len = %return in_stream.readIntLe(T); | |
| 519 | const block_len = try in_stream.readIntLe(T); | |
| 520 | 520 | return parseFormValueRefLen(allocator, in_stream, block_len); |
| 521 | 521 | } |
| 522 | 522 | |
| 523 | 523 | fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue { |
| 524 | 524 | return switch (form_id) { |
| 525 | DW.FORM_addr => FormValue { .Address = %return parseFormValueTargetAddrSize(in_stream) }, | |
| 525 | DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) }, | |
| 526 | 526 | DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1), |
| 527 | 527 | DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2), |
| 528 | 528 | DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4), |
| 529 | 529 | DW.FORM_block => x: { |
| 530 | const block_len = %return readULeb128(in_stream); | |
| 530 | const block_len = try readULeb128(in_stream); | |
| 531 | 531 | return parseFormValueBlockLen(allocator, in_stream, block_len); |
| 532 | 532 | }, |
| 533 | 533 | DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1), |
| ... | ... | @@ -535,35 +535,35 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u |
| 535 | 535 | DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), |
| 536 | 536 | DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8), |
| 537 | 537 | DW.FORM_udata, DW.FORM_sdata => { |
| 538 | const block_len = %return readULeb128(in_stream); | |
| 538 | const block_len = try readULeb128(in_stream); | |
| 539 | 539 | const signed = form_id == DW.FORM_sdata; |
| 540 | 540 | return parseFormValueConstant(allocator, in_stream, signed, block_len); |
| 541 | 541 | }, |
| 542 | 542 | DW.FORM_exprloc => { |
| 543 | const size = %return readULeb128(in_stream); | |
| 544 | const buf = %return readAllocBytes(allocator, in_stream, size); | |
| 543 | const size = try readULeb128(in_stream); | |
| 544 | const buf = try readAllocBytes(allocator, in_stream, size); | |
| 545 | 545 | return FormValue { .ExprLoc = buf }; |
| 546 | 546 | }, |
| 547 | DW.FORM_flag => FormValue { .Flag = (%return in_stream.readByte()) != 0 }, | |
| 547 | DW.FORM_flag => FormValue { .Flag = (try in_stream.readByte()) != 0 }, | |
| 548 | 548 | DW.FORM_flag_present => FormValue { .Flag = true }, |
| 549 | DW.FORM_sec_offset => FormValue { .SecOffset = %return parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 549 | DW.FORM_sec_offset => FormValue { .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 550 | 550 | |
| 551 | 551 | DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8), |
| 552 | 552 | DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16), |
| 553 | 553 | DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32), |
| 554 | 554 | DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64), |
| 555 | 555 | DW.FORM_ref_udata => { |
| 556 | const ref_len = %return readULeb128(in_stream); | |
| 556 | const ref_len = try readULeb128(in_stream); | |
| 557 | 557 | return parseFormValueRefLen(allocator, in_stream, ref_len); |
| 558 | 558 | }, |
| 559 | 559 | |
| 560 | DW.FORM_ref_addr => FormValue { .RefAddr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 561 | DW.FORM_ref_sig8 => FormValue { .RefSig8 = %return in_stream.readIntLe(u64) }, | |
| 560 | DW.FORM_ref_addr => FormValue { .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 561 | DW.FORM_ref_sig8 => FormValue { .RefSig8 = try in_stream.readIntLe(u64) }, | |
| 562 | 562 | |
| 563 | DW.FORM_string => FormValue { .String = %return readStringRaw(allocator, in_stream) }, | |
| 564 | DW.FORM_strp => FormValue { .StrPtr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 563 | DW.FORM_string => FormValue { .String = try readStringRaw(allocator, in_stream) }, | |
| 564 | DW.FORM_strp => FormValue { .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, | |
| 565 | 565 | DW.FORM_indirect => { |
| 566 | const child_form_id = %return readULeb128(in_stream); | |
| 566 | const child_form_id = try readULeb128(in_stream); | |
| 567 | 567 | return parseFormValue(allocator, in_stream, child_form_id, is_64); |
| 568 | 568 | }, |
| 569 | 569 | else => error.InvalidDebugInfo, |
| ... | ... | @@ -576,23 +576,23 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable { |
| 576 | 576 | const in_stream = &in_file_stream.stream; |
| 577 | 577 | var result = AbbrevTable.init(st.allocator()); |
| 578 | 578 | while (true) { |
| 579 | const abbrev_code = %return readULeb128(in_stream); | |
| 579 | const abbrev_code = try readULeb128(in_stream); | |
| 580 | 580 | if (abbrev_code == 0) |
| 581 | 581 | return result; |
| 582 | %return result.append(AbbrevTableEntry { | |
| 582 | try result.append(AbbrevTableEntry { | |
| 583 | 583 | .abbrev_code = abbrev_code, |
| 584 | .tag_id = %return readULeb128(in_stream), | |
| 585 | .has_children = (%return in_stream.readByte()) == DW.CHILDREN_yes, | |
| 584 | .tag_id = try readULeb128(in_stream), | |
| 585 | .has_children = (try in_stream.readByte()) == DW.CHILDREN_yes, | |
| 586 | 586 | .attrs = ArrayList(AbbrevAttr).init(st.allocator()), |
| 587 | 587 | }); |
| 588 | 588 | const attrs = &result.items[result.len - 1].attrs; |
| 589 | 589 | |
| 590 | 590 | while (true) { |
| 591 | const attr_id = %return readULeb128(in_stream); | |
| 592 | const form_id = %return readULeb128(in_stream); | |
| 591 | const attr_id = try readULeb128(in_stream); | |
| 592 | const form_id = try readULeb128(in_stream); | |
| 593 | 593 | if (attr_id == 0 and form_id == 0) |
| 594 | 594 | break; |
| 595 | %return attrs.append(AbbrevAttr { | |
| 595 | try attrs.append(AbbrevAttr { | |
| 596 | 596 | .attr_id = attr_id, |
| 597 | 597 | .form_id = form_id, |
| 598 | 598 | }); |
| ... | ... | @@ -608,10 +608,10 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable |
| 608 | 608 | return &header.table; |
| 609 | 609 | } |
| 610 | 610 | } |
| 611 | %return st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset); | |
| 612 | %return st.abbrev_table_list.append(AbbrevTableHeader { | |
| 611 | try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset); | |
| 612 | try st.abbrev_table_list.append(AbbrevTableHeader { | |
| 613 | 613 | .offset = abbrev_offset, |
| 614 | .table = %return parseAbbrevTable(st), | |
| 614 | .table = try parseAbbrevTable(st), | |
| 615 | 615 | }); |
| 616 | 616 | return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table; |
| 617 | 617 | } |
| ... | ... | @@ -628,7 +628,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) - |
| 628 | 628 | const in_file = &st.self_exe_file; |
| 629 | 629 | var in_file_stream = io.FileInStream.init(in_file); |
| 630 | 630 | const in_stream = &in_file_stream.stream; |
| 631 | const abbrev_code = %return readULeb128(in_stream); | |
| 631 | const abbrev_code = try readULeb128(in_stream); | |
| 632 | 632 | const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo; |
| 633 | 633 | |
| 634 | 634 | var result = Die { |
| ... | ... | @@ -636,18 +636,18 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) - |
| 636 | 636 | .has_children = table_entry.has_children, |
| 637 | 637 | .attrs = ArrayList(Die.Attr).init(st.allocator()), |
| 638 | 638 | }; |
| 639 | %return result.attrs.resize(table_entry.attrs.len); | |
| 639 | try result.attrs.resize(table_entry.attrs.len); | |
| 640 | 640 | for (table_entry.attrs.toSliceConst()) |attr, i| { |
| 641 | 641 | result.attrs.items[i] = Die.Attr { |
| 642 | 642 | .id = attr.attr_id, |
| 643 | .value = %return parseFormValue(st.allocator(), in_stream, attr.form_id, is_64), | |
| 643 | .value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64), | |
| 644 | 644 | }; |
| 645 | 645 | } |
| 646 | 646 | return result; |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | 649 | fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) -> %LineInfo { |
| 650 | const compile_unit_cwd = %return compile_unit.die.getAttrString(st, DW.AT_comp_dir); | |
| 650 | const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir); | |
| 651 | 651 | |
| 652 | 652 | const in_file = &st.self_exe_file; |
| 653 | 653 | const debug_line_end = st.debug_line.offset + st.debug_line.size; |
| ... | ... | @@ -658,10 +658,10 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 658 | 658 | const in_stream = &in_file_stream.stream; |
| 659 | 659 | |
| 660 | 660 | while (this_offset < debug_line_end) : (this_index += 1) { |
| 661 | %return in_file.seekTo(this_offset); | |
| 661 | try in_file.seekTo(this_offset); | |
| 662 | 662 | |
| 663 | 663 | var is_64: bool = undefined; |
| 664 | const unit_length = %return readInitialLength(in_stream, &is_64); | |
| 664 | const unit_length = try readInitialLength(in_stream, &is_64); | |
| 665 | 665 | if (unit_length == 0) |
| 666 | 666 | return error.MissingDebugInfo; |
| 667 | 667 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| ... | ... | @@ -671,37 +671,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 671 | 671 | continue; |
| 672 | 672 | } |
| 673 | 673 | |
| 674 | const version = %return in_stream.readInt(st.elf.endian, u16); | |
| 674 | const version = try in_stream.readInt(st.elf.endian, u16); | |
| 675 | 675 | if (version != 2) return error.InvalidDebugInfo; |
| 676 | 676 | |
| 677 | const prologue_length = %return in_stream.readInt(st.elf.endian, u32); | |
| 678 | const prog_start_offset = (%return in_file.getPos()) + prologue_length; | |
| 677 | const prologue_length = try in_stream.readInt(st.elf.endian, u32); | |
| 678 | const prog_start_offset = (try in_file.getPos()) + prologue_length; | |
| 679 | 679 | |
| 680 | const minimum_instruction_length = %return in_stream.readByte(); | |
| 680 | const minimum_instruction_length = try in_stream.readByte(); | |
| 681 | 681 | if (minimum_instruction_length == 0) return error.InvalidDebugInfo; |
| 682 | 682 | |
| 683 | const default_is_stmt = (%return in_stream.readByte()) != 0; | |
| 684 | const line_base = %return in_stream.readByteSigned(); | |
| 683 | const default_is_stmt = (try in_stream.readByte()) != 0; | |
| 684 | const line_base = try in_stream.readByteSigned(); | |
| 685 | 685 | |
| 686 | const line_range = %return in_stream.readByte(); | |
| 686 | const line_range = try in_stream.readByte(); | |
| 687 | 687 | if (line_range == 0) |
| 688 | 688 | return error.InvalidDebugInfo; |
| 689 | 689 | |
| 690 | const opcode_base = %return in_stream.readByte(); | |
| 690 | const opcode_base = try in_stream.readByte(); | |
| 691 | 691 | |
| 692 | const standard_opcode_lengths = %return st.allocator().alloc(u8, opcode_base - 1); | |
| 692 | const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1); | |
| 693 | 693 | |
| 694 | 694 | {var i: usize = 0; while (i < opcode_base - 1) : (i += 1) { |
| 695 | standard_opcode_lengths[i] = %return in_stream.readByte(); | |
| 695 | standard_opcode_lengths[i] = try in_stream.readByte(); | |
| 696 | 696 | }} |
| 697 | 697 | |
| 698 | 698 | var include_directories = ArrayList([]u8).init(st.allocator()); |
| 699 | %return include_directories.append(compile_unit_cwd); | |
| 699 | try include_directories.append(compile_unit_cwd); | |
| 700 | 700 | while (true) { |
| 701 | const dir = %return st.readString(); | |
| 701 | const dir = try st.readString(); | |
| 702 | 702 | if (dir.len == 0) |
| 703 | 703 | break; |
| 704 | %return include_directories.append(dir); | |
| 704 | try include_directories.append(dir); | |
| 705 | 705 | } |
| 706 | 706 | |
| 707 | 707 | var file_entries = ArrayList(FileEntry).init(st.allocator()); |
| ... | ... | @@ -709,13 +709,13 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 709 | 709 | &file_entries, target_address); |
| 710 | 710 | |
| 711 | 711 | while (true) { |
| 712 | const file_name = %return st.readString(); | |
| 712 | const file_name = try st.readString(); | |
| 713 | 713 | if (file_name.len == 0) |
| 714 | 714 | break; |
| 715 | const dir_index = %return readULeb128(in_stream); | |
| 716 | const mtime = %return readULeb128(in_stream); | |
| 717 | const len_bytes = %return readULeb128(in_stream); | |
| 718 | %return file_entries.append(FileEntry { | |
| 715 | const dir_index = try readULeb128(in_stream); | |
| 716 | const mtime = try readULeb128(in_stream); | |
| 717 | const len_bytes = try readULeb128(in_stream); | |
| 718 | try file_entries.append(FileEntry { | |
| 719 | 719 | .file_name = file_name, |
| 720 | 720 | .dir_index = dir_index, |
| 721 | 721 | .mtime = mtime, |
| ... | ... | @@ -723,33 +723,33 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 723 | 723 | }); |
| 724 | 724 | } |
| 725 | 725 | |
| 726 | %return in_file.seekTo(prog_start_offset); | |
| 726 | try in_file.seekTo(prog_start_offset); | |
| 727 | 727 | |
| 728 | 728 | while (true) { |
| 729 | const opcode = %return in_stream.readByte(); | |
| 729 | const opcode = try in_stream.readByte(); | |
| 730 | 730 | |
| 731 | 731 | var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash |
| 732 | 732 | if (opcode == DW.LNS_extended_op) { |
| 733 | const op_size = %return readULeb128(in_stream); | |
| 733 | const op_size = try readULeb128(in_stream); | |
| 734 | 734 | if (op_size < 1) |
| 735 | 735 | return error.InvalidDebugInfo; |
| 736 | sub_op = %return in_stream.readByte(); | |
| 736 | sub_op = try in_stream.readByte(); | |
| 737 | 737 | switch (sub_op) { |
| 738 | 738 | DW.LNE_end_sequence => { |
| 739 | 739 | prog.end_sequence = true; |
| 740 | if (%return prog.checkLineMatch()) |info| return info; | |
| 740 | if (try prog.checkLineMatch()) |info| return info; | |
| 741 | 741 | return error.MissingDebugInfo; |
| 742 | 742 | }, |
| 743 | 743 | DW.LNE_set_address => { |
| 744 | const addr = %return in_stream.readInt(st.elf.endian, usize); | |
| 744 | const addr = try in_stream.readInt(st.elf.endian, usize); | |
| 745 | 745 | prog.address = addr; |
| 746 | 746 | }, |
| 747 | 747 | DW.LNE_define_file => { |
| 748 | const file_name = %return st.readString(); | |
| 749 | const dir_index = %return readULeb128(in_stream); | |
| 750 | const mtime = %return readULeb128(in_stream); | |
| 751 | const len_bytes = %return readULeb128(in_stream); | |
| 752 | %return file_entries.append(FileEntry { | |
| 748 | const file_name = try st.readString(); | |
| 749 | const dir_index = try readULeb128(in_stream); | |
| 750 | const mtime = try readULeb128(in_stream); | |
| 751 | const len_bytes = try readULeb128(in_stream); | |
| 752 | try file_entries.append(FileEntry { | |
| 753 | 753 | .file_name = file_name, |
| 754 | 754 | .dir_index = dir_index, |
| 755 | 755 | .mtime = mtime, |
| ... | ... | @@ -757,8 +757,8 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 757 | 757 | }); |
| 758 | 758 | }, |
| 759 | 759 | else => { |
| 760 | const fwd_amt = math.cast(isize, op_size - 1) %% return error.InvalidDebugInfo; | |
| 761 | %return in_file.seekForward(fwd_amt); | |
| 760 | const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo; | |
| 761 | try in_file.seekForward(fwd_amt); | |
| 762 | 762 | }, |
| 763 | 763 | } |
| 764 | 764 | } else if (opcode >= opcode_base) { |
| ... | ... | @@ -768,28 +768,28 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 768 | 768 | const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); |
| 769 | 769 | prog.line += inc_line; |
| 770 | 770 | prog.address += inc_addr; |
| 771 | if (%return prog.checkLineMatch()) |info| return info; | |
| 771 | if (try prog.checkLineMatch()) |info| return info; | |
| 772 | 772 | prog.basic_block = false; |
| 773 | 773 | } else { |
| 774 | 774 | switch (opcode) { |
| 775 | 775 | DW.LNS_copy => { |
| 776 | if (%return prog.checkLineMatch()) |info| return info; | |
| 776 | if (try prog.checkLineMatch()) |info| return info; | |
| 777 | 777 | prog.basic_block = false; |
| 778 | 778 | }, |
| 779 | 779 | DW.LNS_advance_pc => { |
| 780 | const arg = %return readULeb128(in_stream); | |
| 780 | const arg = try readULeb128(in_stream); | |
| 781 | 781 | prog.address += arg * minimum_instruction_length; |
| 782 | 782 | }, |
| 783 | 783 | DW.LNS_advance_line => { |
| 784 | const arg = %return readILeb128(in_stream); | |
| 784 | const arg = try readILeb128(in_stream); | |
| 785 | 785 | prog.line += arg; |
| 786 | 786 | }, |
| 787 | 787 | DW.LNS_set_file => { |
| 788 | const arg = %return readULeb128(in_stream); | |
| 788 | const arg = try readULeb128(in_stream); | |
| 789 | 789 | prog.file = arg; |
| 790 | 790 | }, |
| 791 | 791 | DW.LNS_set_column => { |
| 792 | const arg = %return readULeb128(in_stream); | |
| 792 | const arg = try readULeb128(in_stream); | |
| 793 | 793 | prog.column = arg; |
| 794 | 794 | }, |
| 795 | 795 | DW.LNS_negate_stmt => { |
| ... | ... | @@ -803,7 +803,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 803 | 803 | prog.address += inc_addr; |
| 804 | 804 | }, |
| 805 | 805 | DW.LNS_fixed_advance_pc => { |
| 806 | const arg = %return in_stream.readInt(st.elf.endian, u16); | |
| 806 | const arg = try in_stream.readInt(st.elf.endian, u16); | |
| 807 | 807 | prog.address += arg; |
| 808 | 808 | }, |
| 809 | 809 | DW.LNS_set_prologue_end => { |
| ... | ... | @@ -812,7 +812,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe |
| 812 | 812 | if (opcode - 1 >= standard_opcode_lengths.len) |
| 813 | 813 | return error.InvalidDebugInfo; |
| 814 | 814 | const len_bytes = standard_opcode_lengths[opcode - 1]; |
| 815 | %return in_file.seekForward(len_bytes); | |
| 815 | try in_file.seekForward(len_bytes); | |
| 816 | 816 | }, |
| 817 | 817 | } |
| 818 | 818 | } |
| ... | ... | @@ -833,31 +833,31 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 833 | 833 | const in_stream = &in_file_stream.stream; |
| 834 | 834 | |
| 835 | 835 | while (this_unit_offset < debug_info_end) { |
| 836 | %return st.self_exe_file.seekTo(this_unit_offset); | |
| 836 | try st.self_exe_file.seekTo(this_unit_offset); | |
| 837 | 837 | |
| 838 | 838 | var is_64: bool = undefined; |
| 839 | const unit_length = %return readInitialLength(in_stream, &is_64); | |
| 839 | const unit_length = try readInitialLength(in_stream, &is_64); | |
| 840 | 840 | if (unit_length == 0) |
| 841 | 841 | return; |
| 842 | 842 | const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); |
| 843 | 843 | |
| 844 | const version = %return in_stream.readInt(st.elf.endian, u16); | |
| 844 | const version = try in_stream.readInt(st.elf.endian, u16); | |
| 845 | 845 | if (version < 2 or version > 5) return error.InvalidDebugInfo; |
| 846 | 846 | |
| 847 | 847 | const debug_abbrev_offset = |
| 848 | if (is_64) %return in_stream.readInt(st.elf.endian, u64) | |
| 849 | else %return in_stream.readInt(st.elf.endian, u32); | |
| 848 | if (is_64) try in_stream.readInt(st.elf.endian, u64) | |
| 849 | else try in_stream.readInt(st.elf.endian, u32); | |
| 850 | 850 | |
| 851 | const address_size = %return in_stream.readByte(); | |
| 851 | const address_size = try in_stream.readByte(); | |
| 852 | 852 | if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo; |
| 853 | 853 | |
| 854 | const compile_unit_pos = %return st.self_exe_file.getPos(); | |
| 855 | const abbrev_table = %return getAbbrevTable(st, debug_abbrev_offset); | |
| 854 | const compile_unit_pos = try st.self_exe_file.getPos(); | |
| 855 | const abbrev_table = try getAbbrevTable(st, debug_abbrev_offset); | |
| 856 | 856 | |
| 857 | %return st.self_exe_file.seekTo(compile_unit_pos); | |
| 857 | try st.self_exe_file.seekTo(compile_unit_pos); | |
| 858 | 858 | |
| 859 | const compile_unit_die = %return st.allocator().create(Die); | |
| 860 | *compile_unit_die = %return parseDie(st, abbrev_table, is_64); | |
| 859 | const compile_unit_die = try st.allocator().create(Die); | |
| 860 | *compile_unit_die = try parseDie(st, abbrev_table, is_64); | |
| 861 | 861 | |
| 862 | 862 | if (compile_unit_die.tag_id != DW.TAG_compile_unit) |
| 863 | 863 | return error.InvalidDebugInfo; |
| ... | ... | @@ -868,7 +868,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 868 | 868 | const pc_end = switch (*high_pc_value) { |
| 869 | 869 | FormValue.Address => |value| value, |
| 870 | 870 | FormValue.Const => |value| b: { |
| 871 | const offset = %return value.asUnsignedLe(); | |
| 871 | const offset = try value.asUnsignedLe(); | |
| 872 | 872 | break :b (low_pc + offset); |
| 873 | 873 | }, |
| 874 | 874 | else => return error.InvalidDebugInfo, |
| ... | ... | @@ -887,7 +887,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void { |
| 887 | 887 | } |
| 888 | 888 | }; |
| 889 | 889 | |
| 890 | %return st.compile_unit_list.append(CompileUnit { | |
| 890 | try st.compile_unit_list.append(CompileUnit { | |
| 891 | 891 | .version = version, |
| 892 | 892 | .is_64 = is_64, |
| 893 | 893 | .pc_range = pc_range, |
| ... | ... | @@ -911,10 +911,10 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn |
| 911 | 911 | if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| { |
| 912 | 912 | var base_address: usize = 0; |
| 913 | 913 | if (st.debug_ranges) |debug_ranges| { |
| 914 | %return st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset); | |
| 914 | try st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset); | |
| 915 | 915 | while (true) { |
| 916 | const begin_addr = %return in_stream.readIntLe(usize); | |
| 917 | const end_addr = %return in_stream.readIntLe(usize); | |
| 916 | const begin_addr = try in_stream.readIntLe(usize); | |
| 917 | const end_addr = try in_stream.readIntLe(usize); | |
| 918 | 918 | if (begin_addr == 0 and end_addr == 0) { |
| 919 | 919 | break; |
| 920 | 920 | } |
| ... | ... | @@ -937,7 +937,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn |
| 937 | 937 | } |
| 938 | 938 | |
| 939 | 939 | fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 { |
| 940 | const first_32_bits = %return in_stream.readIntLe(u32); | |
| 940 | const first_32_bits = try in_stream.readIntLe(u32); | |
| 941 | 941 | *is_64 = (first_32_bits == 0xffffffff); |
| 942 | 942 | if (*is_64) { |
| 943 | 943 | return in_stream.readIntLe(u64); |
| ... | ... | @@ -952,7 +952,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 { |
| 952 | 952 | var shift: usize = 0; |
| 953 | 953 | |
| 954 | 954 | while (true) { |
| 955 | const byte = %return in_stream.readByte(); | |
| 955 | const byte = try in_stream.readByte(); | |
| 956 | 956 | |
| 957 | 957 | var operand: u64 = undefined; |
| 958 | 958 | |
| ... | ... | @@ -973,7 +973,7 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 { |
| 973 | 973 | var shift: usize = 0; |
| 974 | 974 | |
| 975 | 975 | while (true) { |
| 976 | const byte = %return in_stream.readByte(); | |
| 976 | const byte = try in_stream.readByte(); | |
| 977 | 977 | |
| 978 | 978 | var operand: i64 = undefined; |
| 979 | 979 |
std/elf.zig+53-53| ... | ... | @@ -82,8 +82,8 @@ pub const Elf = struct { |
| 82 | 82 | |
| 83 | 83 | /// Call close when done. |
| 84 | 84 | pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) -> %void { |
| 85 | %return elf.prealloc_file.open(path); | |
| 86 | %return elf.openFile(allocator, &elf.prealloc_file); | |
| 85 | try elf.prealloc_file.open(path); | |
| 86 | try elf.openFile(allocator, &elf.prealloc_file); | |
| 87 | 87 | elf.auto_close_stream = true; |
| 88 | 88 | } |
| 89 | 89 | |
| ... | ... | @@ -97,28 +97,28 @@ pub const Elf = struct { |
| 97 | 97 | const in = &file_stream.stream; |
| 98 | 98 | |
| 99 | 99 | var magic: [4]u8 = undefined; |
| 100 | %return in.readNoEof(magic[0..]); | |
| 100 | try in.readNoEof(magic[0..]); | |
| 101 | 101 | if (!mem.eql(u8, magic, "\x7fELF")) return error.InvalidFormat; |
| 102 | 102 | |
| 103 | elf.is_64 = switch (%return in.readByte()) { | |
| 103 | elf.is_64 = switch (try in.readByte()) { | |
| 104 | 104 | 1 => false, |
| 105 | 105 | 2 => true, |
| 106 | 106 | else => return error.InvalidFormat, |
| 107 | 107 | }; |
| 108 | 108 | |
| 109 | elf.endian = switch (%return in.readByte()) { | |
| 109 | elf.endian = switch (try in.readByte()) { | |
| 110 | 110 | 1 => builtin.Endian.Little, |
| 111 | 111 | 2 => builtin.Endian.Big, |
| 112 | 112 | else => return error.InvalidFormat, |
| 113 | 113 | }; |
| 114 | 114 | |
| 115 | const version_byte = %return in.readByte(); | |
| 115 | const version_byte = try in.readByte(); | |
| 116 | 116 | if (version_byte != 1) return error.InvalidFormat; |
| 117 | 117 | |
| 118 | 118 | // skip over padding |
| 119 | %return elf.in_file.seekForward(9); | |
| 119 | try elf.in_file.seekForward(9); | |
| 120 | 120 | |
| 121 | elf.file_type = switch (%return in.readInt(elf.endian, u16)) { | |
| 121 | elf.file_type = switch (try in.readInt(elf.endian, u16)) { | |
| 122 | 122 | 1 => FileType.Relocatable, |
| 123 | 123 | 2 => FileType.Executable, |
| 124 | 124 | 3 => FileType.Shared, |
| ... | ... | @@ -126,7 +126,7 @@ pub const Elf = struct { |
| 126 | 126 | else => return error.InvalidFormat, |
| 127 | 127 | }; |
| 128 | 128 | |
| 129 | elf.arch = switch (%return in.readInt(elf.endian, u16)) { | |
| 129 | elf.arch = switch (try in.readInt(elf.endian, u16)) { | |
| 130 | 130 | 0x02 => Arch.Sparc, |
| 131 | 131 | 0x03 => Arch.x86, |
| 132 | 132 | 0x08 => Arch.Mips, |
| ... | ... | @@ -139,88 +139,88 @@ pub const Elf = struct { |
| 139 | 139 | else => return error.InvalidFormat, |
| 140 | 140 | }; |
| 141 | 141 | |
| 142 | const elf_version = %return in.readInt(elf.endian, u32); | |
| 142 | const elf_version = try in.readInt(elf.endian, u32); | |
| 143 | 143 | if (elf_version != 1) return error.InvalidFormat; |
| 144 | 144 | |
| 145 | 145 | if (elf.is_64) { |
| 146 | elf.entry_addr = %return in.readInt(elf.endian, u64); | |
| 147 | elf.program_header_offset = %return in.readInt(elf.endian, u64); | |
| 148 | elf.section_header_offset = %return in.readInt(elf.endian, u64); | |
| 146 | elf.entry_addr = try in.readInt(elf.endian, u64); | |
| 147 | elf.program_header_offset = try in.readInt(elf.endian, u64); | |
| 148 | elf.section_header_offset = try in.readInt(elf.endian, u64); | |
| 149 | 149 | } else { |
| 150 | elf.entry_addr = u64(%return in.readInt(elf.endian, u32)); | |
| 151 | elf.program_header_offset = u64(%return in.readInt(elf.endian, u32)); | |
| 152 | elf.section_header_offset = u64(%return in.readInt(elf.endian, u32)); | |
| 150 | elf.entry_addr = u64(try in.readInt(elf.endian, u32)); | |
| 151 | elf.program_header_offset = u64(try in.readInt(elf.endian, u32)); | |
| 152 | elf.section_header_offset = u64(try in.readInt(elf.endian, u32)); | |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | // skip over flags |
| 156 | %return elf.in_file.seekForward(4); | |
| 156 | try elf.in_file.seekForward(4); | |
| 157 | 157 | |
| 158 | const header_size = %return in.readInt(elf.endian, u16); | |
| 158 | const header_size = try in.readInt(elf.endian, u16); | |
| 159 | 159 | if ((elf.is_64 and header_size != 64) or |
| 160 | 160 | (!elf.is_64 and header_size != 52)) |
| 161 | 161 | { |
| 162 | 162 | return error.InvalidFormat; |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | const ph_entry_size = %return in.readInt(elf.endian, u16); | |
| 166 | const ph_entry_count = %return in.readInt(elf.endian, u16); | |
| 167 | const sh_entry_size = %return in.readInt(elf.endian, u16); | |
| 168 | const sh_entry_count = %return in.readInt(elf.endian, u16); | |
| 169 | elf.string_section_index = u64(%return in.readInt(elf.endian, u16)); | |
| 165 | const ph_entry_size = try in.readInt(elf.endian, u16); | |
| 166 | const ph_entry_count = try in.readInt(elf.endian, u16); | |
| 167 | const sh_entry_size = try in.readInt(elf.endian, u16); | |
| 168 | const sh_entry_count = try in.readInt(elf.endian, u16); | |
| 169 | elf.string_section_index = u64(try in.readInt(elf.endian, u16)); | |
| 170 | 170 | |
| 171 | 171 | if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat; |
| 172 | 172 | |
| 173 | 173 | const sh_byte_count = u64(sh_entry_size) * u64(sh_entry_count); |
| 174 | const end_sh = %return math.add(u64, elf.section_header_offset, sh_byte_count); | |
| 174 | const end_sh = try math.add(u64, elf.section_header_offset, sh_byte_count); | |
| 175 | 175 | const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count); |
| 176 | const end_ph = %return math.add(u64, elf.program_header_offset, ph_byte_count); | |
| 176 | const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count); | |
| 177 | 177 | |
| 178 | const stream_end = %return elf.in_file.getEndPos(); | |
| 178 | const stream_end = try elf.in_file.getEndPos(); | |
| 179 | 179 | if (stream_end < end_sh or stream_end < end_ph) { |
| 180 | 180 | return error.InvalidFormat; |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | %return elf.in_file.seekTo(elf.section_header_offset); | |
| 183 | try elf.in_file.seekTo(elf.section_header_offset); | |
| 184 | 184 | |
| 185 | elf.section_headers = %return elf.allocator.alloc(SectionHeader, sh_entry_count); | |
| 185 | elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count); | |
| 186 | 186 | %defer elf.allocator.free(elf.section_headers); |
| 187 | 187 | |
| 188 | 188 | if (elf.is_64) { |
| 189 | 189 | if (sh_entry_size != 64) return error.InvalidFormat; |
| 190 | 190 | |
| 191 | 191 | for (elf.section_headers) |*elf_section| { |
| 192 | elf_section.name = %return in.readInt(elf.endian, u32); | |
| 193 | elf_section.sh_type = %return in.readInt(elf.endian, u32); | |
| 194 | elf_section.flags = %return in.readInt(elf.endian, u64); | |
| 195 | elf_section.addr = %return in.readInt(elf.endian, u64); | |
| 196 | elf_section.offset = %return in.readInt(elf.endian, u64); | |
| 197 | elf_section.size = %return in.readInt(elf.endian, u64); | |
| 198 | elf_section.link = %return in.readInt(elf.endian, u32); | |
| 199 | elf_section.info = %return in.readInt(elf.endian, u32); | |
| 200 | elf_section.addr_align = %return in.readInt(elf.endian, u64); | |
| 201 | elf_section.ent_size = %return in.readInt(elf.endian, u64); | |
| 192 | elf_section.name = try in.readInt(elf.endian, u32); | |
| 193 | elf_section.sh_type = try in.readInt(elf.endian, u32); | |
| 194 | elf_section.flags = try in.readInt(elf.endian, u64); | |
| 195 | elf_section.addr = try in.readInt(elf.endian, u64); | |
| 196 | elf_section.offset = try in.readInt(elf.endian, u64); | |
| 197 | elf_section.size = try in.readInt(elf.endian, u64); | |
| 198 | elf_section.link = try in.readInt(elf.endian, u32); | |
| 199 | elf_section.info = try in.readInt(elf.endian, u32); | |
| 200 | elf_section.addr_align = try in.readInt(elf.endian, u64); | |
| 201 | elf_section.ent_size = try in.readInt(elf.endian, u64); | |
| 202 | 202 | } |
| 203 | 203 | } else { |
| 204 | 204 | if (sh_entry_size != 40) return error.InvalidFormat; |
| 205 | 205 | |
| 206 | 206 | for (elf.section_headers) |*elf_section| { |
| 207 | 207 | // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ? |
| 208 | elf_section.name = %return in.readInt(elf.endian, u32); | |
| 209 | elf_section.sh_type = %return in.readInt(elf.endian, u32); | |
| 210 | elf_section.flags = u64(%return in.readInt(elf.endian, u32)); | |
| 211 | elf_section.addr = u64(%return in.readInt(elf.endian, u32)); | |
| 212 | elf_section.offset = u64(%return in.readInt(elf.endian, u32)); | |
| 213 | elf_section.size = u64(%return in.readInt(elf.endian, u32)); | |
| 214 | elf_section.link = %return in.readInt(elf.endian, u32); | |
| 215 | elf_section.info = %return in.readInt(elf.endian, u32); | |
| 216 | elf_section.addr_align = u64(%return in.readInt(elf.endian, u32)); | |
| 217 | elf_section.ent_size = u64(%return in.readInt(elf.endian, u32)); | |
| 208 | elf_section.name = try in.readInt(elf.endian, u32); | |
| 209 | elf_section.sh_type = try in.readInt(elf.endian, u32); | |
| 210 | elf_section.flags = u64(try in.readInt(elf.endian, u32)); | |
| 211 | elf_section.addr = u64(try in.readInt(elf.endian, u32)); | |
| 212 | elf_section.offset = u64(try in.readInt(elf.endian, u32)); | |
| 213 | elf_section.size = u64(try in.readInt(elf.endian, u32)); | |
| 214 | elf_section.link = try in.readInt(elf.endian, u32); | |
| 215 | elf_section.info = try in.readInt(elf.endian, u32); | |
| 216 | elf_section.addr_align = u64(try in.readInt(elf.endian, u32)); | |
| 217 | elf_section.ent_size = u64(try in.readInt(elf.endian, u32)); | |
| 218 | 218 | } |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | 221 | for (elf.section_headers) |*elf_section| { |
| 222 | 222 | if (elf_section.sh_type != SHT_NOBITS) { |
| 223 | const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size); | |
| 223 | const file_end_offset = try math.add(u64, elf_section.offset, elf_section.size); | |
| 224 | 224 | if (stream_end < file_end_offset) return error.InvalidFormat; |
| 225 | 225 | } |
| 226 | 226 | } |
| ... | ... | @@ -247,15 +247,15 @@ pub const Elf = struct { |
| 247 | 247 | if (elf_section.sh_type == SHT_NULL) continue; |
| 248 | 248 | |
| 249 | 249 | const name_offset = elf.string_section.offset + elf_section.name; |
| 250 | %return elf.in_file.seekTo(name_offset); | |
| 250 | try elf.in_file.seekTo(name_offset); | |
| 251 | 251 | |
| 252 | 252 | for (name) |expected_c| { |
| 253 | const target_c = %return in.readByte(); | |
| 253 | const target_c = try in.readByte(); | |
| 254 | 254 | if (target_c == 0 or expected_c != target_c) continue :section_loop; |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | 257 | { |
| 258 | const null_byte = %return in.readByte(); | |
| 258 | const null_byte = try in.readByte(); | |
| 259 | 259 | if (null_byte == 0) return elf_section; |
| 260 | 260 | } |
| 261 | 261 | } |
| ... | ... | @@ -264,6 +264,6 @@ pub const Elf = struct { |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | 266 | pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void { |
| 267 | %return elf.in_file.seekTo(elf_section.offset); | |
| 267 | try elf.in_file.seekTo(elf_section.offset); | |
| 268 | 268 | } |
| 269 | 269 | }; |
std/endian.zig+1-1| ... | ... | @@ -16,5 +16,5 @@ pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T { |
| 16 | 16 | pub fn swap(comptime T: type, x: T) -> T { |
| 17 | 17 | var buf: [@sizeOf(T)]u8 = undefined; |
| 18 | 18 | mem.writeInt(buf[0..], x, false); |
| 19 | return mem.readInt(buf, T, true); | |
| 19 | return mem.readInt(buf, T, builtin.Endian.Big); | |
| 20 | 20 | } |
std/fmt/index.zig+35-35| ... | ... | @@ -40,13 +40,13 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 40 | 40 | State.Start => switch (c) { |
| 41 | 41 | '{' => { |
| 42 | 42 | if (start_index < i) { |
| 43 | %return output(context, fmt[start_index..i]); | |
| 43 | try output(context, fmt[start_index..i]); | |
| 44 | 44 | } |
| 45 | 45 | state = State.OpenBrace; |
| 46 | 46 | }, |
| 47 | 47 | '}' => { |
| 48 | 48 | if (start_index < i) { |
| 49 | %return output(context, fmt[start_index..i]); | |
| 49 | try output(context, fmt[start_index..i]); | |
| 50 | 50 | } |
| 51 | 51 | state = State.CloseBrace; |
| 52 | 52 | }, |
| ... | ... | @@ -58,7 +58,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 58 | 58 | start_index = i; |
| 59 | 59 | }, |
| 60 | 60 | '}' => { |
| 61 | %return formatValue(args[next_arg], context, output); | |
| 61 | try formatValue(args[next_arg], context, output); | |
| 62 | 62 | next_arg += 1; |
| 63 | 63 | state = State.Start; |
| 64 | 64 | start_index = i + 1; |
| ... | ... | @@ -110,7 +110,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 110 | 110 | }, |
| 111 | 111 | State.Integer => switch (c) { |
| 112 | 112 | '}' => { |
| 113 | %return formatInt(args[next_arg], radix, uppercase, width, context, output); | |
| 113 | try formatInt(args[next_arg], radix, uppercase, width, context, output); | |
| 114 | 114 | next_arg += 1; |
| 115 | 115 | state = State.Start; |
| 116 | 116 | start_index = i + 1; |
| ... | ... | @@ -124,7 +124,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 124 | 124 | State.IntegerWidth => switch (c) { |
| 125 | 125 | '}' => { |
| 126 | 126 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); |
| 127 | %return formatInt(args[next_arg], radix, uppercase, width, context, output); | |
| 127 | try formatInt(args[next_arg], radix, uppercase, width, context, output); | |
| 128 | 128 | next_arg += 1; |
| 129 | 129 | state = State.Start; |
| 130 | 130 | start_index = i + 1; |
| ... | ... | @@ -134,7 +134,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 134 | 134 | }, |
| 135 | 135 | State.Float => switch (c) { |
| 136 | 136 | '}' => { |
| 137 | %return formatFloatDecimal(args[next_arg], 0, context, output); | |
| 137 | try formatFloatDecimal(args[next_arg], 0, context, output); | |
| 138 | 138 | next_arg += 1; |
| 139 | 139 | state = State.Start; |
| 140 | 140 | start_index = i + 1; |
| ... | ... | @@ -148,7 +148,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 148 | 148 | State.FloatWidth => switch (c) { |
| 149 | 149 | '}' => { |
| 150 | 150 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); |
| 151 | %return formatFloatDecimal(args[next_arg], width, context, output); | |
| 151 | try formatFloatDecimal(args[next_arg], width, context, output); | |
| 152 | 152 | next_arg += 1; |
| 153 | 153 | state = State.Start; |
| 154 | 154 | start_index = i + 1; |
| ... | ... | @@ -159,7 +159,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 159 | 159 | State.BufWidth => switch (c) { |
| 160 | 160 | '}' => { |
| 161 | 161 | width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10); |
| 162 | %return formatBuf(args[next_arg], width, context, output); | |
| 162 | try formatBuf(args[next_arg], width, context, output); | |
| 163 | 163 | next_arg += 1; |
| 164 | 164 | state = State.Start; |
| 165 | 165 | start_index = i + 1; |
| ... | ... | @@ -169,7 +169,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 169 | 169 | }, |
| 170 | 170 | State.Character => switch (c) { |
| 171 | 171 | '}' => { |
| 172 | %return formatAsciiChar(args[next_arg], context, output); | |
| 172 | try formatAsciiChar(args[next_arg], context, output); | |
| 173 | 173 | next_arg += 1; |
| 174 | 174 | state = State.Start; |
| 175 | 175 | start_index = i + 1; |
| ... | ... | @@ -187,7 +187,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void, |
| 187 | 187 | } |
| 188 | 188 | } |
| 189 | 189 | if (start_index < fmt.len) { |
| 190 | %return output(context, fmt[start_index..]); | |
| 190 | try output(context, fmt[start_index..]); | |
| 191 | 191 | } |
| 192 | 192 | } |
| 193 | 193 | |
| ... | ... | @@ -221,7 +221,7 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons |
| 221 | 221 | } |
| 222 | 222 | }, |
| 223 | 223 | builtin.TypeId.Error => { |
| 224 | %return output(context, "error."); | |
| 224 | try output(context, "error."); | |
| 225 | 225 | return output(context, @errorName(value)); |
| 226 | 226 | }, |
| 227 | 227 | builtin.TypeId.Pointer => { |
| ... | ... | @@ -247,12 +247,12 @@ pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const |
| 247 | 247 | pub fn formatBuf(buf: []const u8, width: usize, |
| 248 | 248 | context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void |
| 249 | 249 | { |
| 250 | %return output(context, buf); | |
| 250 | try output(context, buf); | |
| 251 | 251 | |
| 252 | 252 | var leftover_padding = if (width > buf.len) (width - buf.len) else return; |
| 253 | 253 | const pad_byte: u8 = ' '; |
| 254 | 254 | while (leftover_padding > 0) : (leftover_padding -= 1) { |
| 255 | %return output(context, (&pad_byte)[0..1]); | |
| 255 | try output(context, (&pad_byte)[0..1]); | |
| 256 | 256 | } |
| 257 | 257 | } |
| 258 | 258 | |
| ... | ... | @@ -264,7 +264,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons |
| 264 | 264 | return output(context, "NaN"); |
| 265 | 265 | } |
| 266 | 266 | if (math.signbit(x)) { |
| 267 | %return output(context, "-"); | |
| 267 | try output(context, "-"); | |
| 268 | 268 | x = -x; |
| 269 | 269 | } |
| 270 | 270 | if (math.isPositiveInf(x)) { |
| ... | ... | @@ -276,21 +276,21 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons |
| 276 | 276 | |
| 277 | 277 | var buffer: [32]u8 = undefined; |
| 278 | 278 | const float_decimal = errol3(x, buffer[0..]); |
| 279 | %return output(context, float_decimal.digits[0..1]); | |
| 280 | %return output(context, "."); | |
| 279 | try output(context, float_decimal.digits[0..1]); | |
| 280 | try output(context, "."); | |
| 281 | 281 | if (float_decimal.digits.len > 1) { |
| 282 | 282 | const num_digits = if (@typeOf(value) == f32) |
| 283 | 283 | math.min(usize(9), float_decimal.digits.len) |
| 284 | 284 | else |
| 285 | 285 | float_decimal.digits.len; |
| 286 | %return output(context, float_decimal.digits[1 .. num_digits]); | |
| 286 | try output(context, float_decimal.digits[1 .. num_digits]); | |
| 287 | 287 | } else { |
| 288 | %return output(context, "0"); | |
| 288 | try output(context, "0"); | |
| 289 | 289 | } |
| 290 | 290 | |
| 291 | 291 | if (float_decimal.exp != 1) { |
| 292 | %return output(context, "e"); | |
| 293 | %return formatInt(float_decimal.exp - 1, 10, false, 0, context, output); | |
| 292 | try output(context, "e"); | |
| 293 | try formatInt(float_decimal.exp - 1, 10, false, 0, context, output); | |
| 294 | 294 | } |
| 295 | 295 | } |
| 296 | 296 | |
| ... | ... | @@ -302,7 +302,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn |
| 302 | 302 | return output(context, "NaN"); |
| 303 | 303 | } |
| 304 | 304 | if (math.signbit(x)) { |
| 305 | %return output(context, "-"); | |
| 305 | try output(context, "-"); | |
| 306 | 306 | x = -x; |
| 307 | 307 | } |
| 308 | 308 | if (math.isPositiveInf(x)) { |
| ... | ... | @@ -317,8 +317,8 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn |
| 317 | 317 | |
| 318 | 318 | const num_left_digits = if (float_decimal.exp > 0) usize(float_decimal.exp) else 1; |
| 319 | 319 | |
| 320 | %return output(context, float_decimal.digits[0 .. num_left_digits]); | |
| 321 | %return output(context, "."); | |
| 320 | try output(context, float_decimal.digits[0 .. num_left_digits]); | |
| 321 | try output(context, "."); | |
| 322 | 322 | if (float_decimal.digits.len > 1) { |
| 323 | 323 | const num_valid_digtis = if (@typeOf(value) == f32) math.min(usize(7), float_decimal.digits.len) |
| 324 | 324 | else |
| ... | ... | @@ -328,9 +328,9 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn |
| 328 | 328 | math.min(precision, (num_valid_digtis-num_left_digits)) |
| 329 | 329 | else |
| 330 | 330 | num_valid_digtis - num_left_digits; |
| 331 | %return output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]); | |
| 331 | try output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]); | |
| 332 | 332 | } else { |
| 333 | %return output(context, "0"); | |
| 333 | try output(context, "0"); | |
| 334 | 334 | } |
| 335 | 335 | } |
| 336 | 336 | |
| ... | ... | @@ -351,7 +351,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, |
| 351 | 351 | const uint = @IntType(false, @typeOf(value).bit_count); |
| 352 | 352 | if (value < 0) { |
| 353 | 353 | const minus_sign: u8 = '-'; |
| 354 | %return output(context, (&minus_sign)[0..1]); | |
| 354 | try output(context, (&minus_sign)[0..1]); | |
| 355 | 355 | const new_value = uint(-(value + 1)) + 1; |
| 356 | 356 | const new_width = if (width == 0) 0 else (width - 1); |
| 357 | 357 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, output); |
| ... | ... | @@ -359,7 +359,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, |
| 359 | 359 | return formatIntUnsigned(uint(value), base, uppercase, width, context, output); |
| 360 | 360 | } else { |
| 361 | 361 | const plus_sign: u8 = '+'; |
| 362 | %return output(context, (&plus_sign)[0..1]); | |
| 362 | try output(context, (&plus_sign)[0..1]); | |
| 363 | 363 | const new_value = uint(value); |
| 364 | 364 | const new_width = if (width == 0) 0 else (width - 1); |
| 365 | 365 | return formatIntUnsigned(new_value, base, uppercase, new_width, context, output); |
| ... | ... | @@ -391,7 +391,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, |
| 391 | 391 | const zero_byte: u8 = '0'; |
| 392 | 392 | var leftover_padding = padding - index; |
| 393 | 393 | while (true) { |
| 394 | %return output(context, (&zero_byte)[0..1]); | |
| 394 | try output(context, (&zero_byte)[0..1]); | |
| 395 | 395 | leftover_padding -= 1; |
| 396 | 396 | if (leftover_padding == 0) |
| 397 | 397 | break; |
| ... | ... | @@ -428,7 +428,7 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) -> %T { |
| 428 | 428 | if (buf.len == 0) |
| 429 | 429 | return T(0); |
| 430 | 430 | if (buf[0] == '-') { |
| 431 | return math.negate(%return parseUnsigned(T, buf[1..], radix)); | |
| 431 | return math.negate(try parseUnsigned(T, buf[1..], radix)); | |
| 432 | 432 | } else if (buf[0] == '+') { |
| 433 | 433 | return parseUnsigned(T, buf[1..], radix); |
| 434 | 434 | } else { |
| ... | ... | @@ -450,9 +450,9 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T { |
| 450 | 450 | var x: T = 0; |
| 451 | 451 | |
| 452 | 452 | for (buf) |c| { |
| 453 | const digit = %return charToDigit(c, radix); | |
| 454 | x = %return math.mul(T, x, radix); | |
| 455 | x = %return math.add(T, x, digit); | |
| 453 | const digit = try charToDigit(c, radix); | |
| 454 | x = try math.mul(T, x, radix); | |
| 455 | x = try math.add(T, x, digit); | |
| 456 | 456 | } |
| 457 | 457 | |
| 458 | 458 | return x; |
| ... | ... | @@ -494,7 +494,7 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void { |
| 494 | 494 | |
| 495 | 495 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 { |
| 496 | 496 | var context = BufPrintContext { .remaining = buf, }; |
| 497 | %return format(&context, bufPrintWrite, fmt, args); | |
| 497 | try format(&context, bufPrintWrite, fmt, args); | |
| 498 | 498 | return buf[0..buf.len - context.remaining.len]; |
| 499 | 499 | } |
| 500 | 500 | |
| ... | ... | @@ -502,7 +502,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ... |
| 502 | 502 | var size: usize = 0; |
| 503 | 503 | // Cannot fail because `countSize` cannot fail. |
| 504 | 504 | %%format(&size, countSize, fmt, args); |
| 505 | const buf = %return allocator.alloc(u8, size); | |
| 505 | const buf = try allocator.alloc(u8, size); | |
| 506 | 506 | return bufPrint(buf, fmt, args); |
| 507 | 507 | } |
| 508 | 508 | |
| ... | ... | @@ -533,7 +533,7 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: u |
| 533 | 533 | } |
| 534 | 534 | |
| 535 | 535 | test "parse u64 digit too big" { |
| 536 | _ = parseUnsigned(u64, "123a", 10) %% |err| { | |
| 536 | _ = parseUnsigned(u64, "123a", 10) catch |err| { | |
| 537 | 537 | if (err == error.InvalidChar) return; |
| 538 | 538 | unreachable; |
| 539 | 539 | }; |
std/hash_map.zig+3-3| ... | ... | @@ -83,14 +83,14 @@ pub fn HashMap(comptime K: type, comptime V: type, |
| 83 | 83 | /// Returns the value that was already there. |
| 84 | 84 | pub fn put(hm: &Self, key: K, value: &const V) -> %?V { |
| 85 | 85 | if (hm.entries.len == 0) { |
| 86 | %return hm.initCapacity(16); | |
| 86 | try hm.initCapacity(16); | |
| 87 | 87 | } |
| 88 | 88 | hm.incrementModificationCount(); |
| 89 | 89 | |
| 90 | 90 | // if we get too full (60%), double the capacity |
| 91 | 91 | if (hm.size * 5 >= hm.entries.len * 3) { |
| 92 | 92 | const old_entries = hm.entries; |
| 93 | %return hm.initCapacity(hm.entries.len * 2); | |
| 93 | try hm.initCapacity(hm.entries.len * 2); | |
| 94 | 94 | // dump all of the old elements into the new table |
| 95 | 95 | for (old_entries) |*old_entry| { |
| 96 | 96 | if (old_entry.used) { |
| ... | ... | @@ -149,7 +149,7 @@ pub fn HashMap(comptime K: type, comptime V: type, |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | 151 | fn initCapacity(hm: &Self, capacity: usize) -> %void { |
| 152 | hm.entries = %return hm.allocator.alloc(Entry, capacity); | |
| 152 | hm.entries = try hm.allocator.alloc(Entry, capacity); | |
| 153 | 153 | hm.size = 0; |
| 154 | 154 | hm.max_distance_from_start_index = 0; |
| 155 | 155 | for (hm.entries) |*entry| { |
std/heap.zig+5-5| ... | ... | @@ -49,7 +49,7 @@ pub const IncrementingAllocator = struct { |
| 49 | 49 | |
| 50 | 50 | fn init(capacity: usize) -> %IncrementingAllocator { |
| 51 | 51 | switch (builtin.os) { |
| 52 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | |
| 52 | Os.linux, Os.macosx, Os.ios => { | |
| 53 | 53 | const p = os.posix; |
| 54 | 54 | const addr = p.mmap(null, capacity, p.PROT_READ|p.PROT_WRITE, |
| 55 | 55 | p.MAP_PRIVATE|p.MAP_ANONYMOUS|p.MAP_NORESERVE, -1, 0); |
| ... | ... | @@ -87,7 +87,7 @@ pub const IncrementingAllocator = struct { |
| 87 | 87 | |
| 88 | 88 | fn deinit(self: &IncrementingAllocator) { |
| 89 | 89 | switch (builtin.os) { |
| 90 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | |
| 90 | Os.linux, Os.macosx, Os.ios => { | |
| 91 | 91 | _ = os.posix.munmap(self.bytes.ptr, self.bytes.len); |
| 92 | 92 | }, |
| 93 | 93 | Os.windows => { |
| ... | ... | @@ -124,7 +124,7 @@ pub const IncrementingAllocator = struct { |
| 124 | 124 | if (new_size <= old_mem.len) { |
| 125 | 125 | return old_mem[0..new_size]; |
| 126 | 126 | } else { |
| 127 | const result = %return alloc(allocator, new_size, alignment); | |
| 127 | const result = try alloc(allocator, new_size, alignment); | |
| 128 | 128 | mem.copy(u8, result, old_mem); |
| 129 | 129 | return result; |
| 130 | 130 | } |
| ... | ... | @@ -137,9 +137,9 @@ pub const IncrementingAllocator = struct { |
| 137 | 137 | |
| 138 | 138 | test "c_allocator" { |
| 139 | 139 | if (builtin.link_libc) { |
| 140 | var slice = c_allocator.alloc(u8, 50) %% return; | |
| 140 | var slice = c_allocator.alloc(u8, 50) catch return; | |
| 141 | 141 | defer c_allocator.free(slice); |
| 142 | slice = c_allocator.realloc(u8, slice, 100) %% return; | |
| 142 | slice = c_allocator.realloc(u8, slice, 100) catch return; | |
| 143 | 143 | } |
| 144 | 144 | } |
| 145 | 145 |
std/io.zig+38-38| ... | ... | @@ -3,7 +3,7 @@ const builtin = @import("builtin"); |
| 3 | 3 | const Os = builtin.Os; |
| 4 | 4 | const system = switch(builtin.os) { |
| 5 | 5 | Os.linux => @import("os/linux.zig"), |
| 6 | Os.darwin, Os.macosx, Os.ios => @import("os/darwin.zig"), | |
| 6 | Os.macosx, Os.ios => @import("os/darwin.zig"), | |
| 7 | 7 | Os.windows => @import("os/windows/index.zig"), |
| 8 | 8 | else => @compileError("Unsupported OS"), |
| 9 | 9 | }; |
| ... | ... | @@ -51,7 +51,7 @@ error EndOfFile; |
| 51 | 51 | |
| 52 | 52 | pub fn getStdErr() -> %File { |
| 53 | 53 | const handle = if (is_windows) |
| 54 | %return os.windowsGetStdHandle(system.STD_ERROR_HANDLE) | |
| 54 | try os.windowsGetStdHandle(system.STD_ERROR_HANDLE) | |
| 55 | 55 | else if (is_posix) |
| 56 | 56 | system.STDERR_FILENO |
| 57 | 57 | else |
| ... | ... | @@ -61,7 +61,7 @@ pub fn getStdErr() -> %File { |
| 61 | 61 | |
| 62 | 62 | pub fn getStdOut() -> %File { |
| 63 | 63 | const handle = if (is_windows) |
| 64 | %return os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE) | |
| 64 | try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE) | |
| 65 | 65 | else if (is_posix) |
| 66 | 66 | system.STDOUT_FILENO |
| 67 | 67 | else |
| ... | ... | @@ -71,7 +71,7 @@ pub fn getStdOut() -> %File { |
| 71 | 71 | |
| 72 | 72 | pub fn getStdIn() -> %File { |
| 73 | 73 | const handle = if (is_windows) |
| 74 | %return os.windowsGetStdHandle(system.STD_INPUT_HANDLE) | |
| 74 | try os.windowsGetStdHandle(system.STD_INPUT_HANDLE) | |
| 75 | 75 | else if (is_posix) |
| 76 | 76 | system.STDIN_FILENO |
| 77 | 77 | else |
| ... | ... | @@ -131,10 +131,10 @@ pub const File = struct { |
| 131 | 131 | pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) -> %File { |
| 132 | 132 | if (is_posix) { |
| 133 | 133 | const flags = system.O_LARGEFILE|system.O_RDONLY; |
| 134 | const fd = %return os.posixOpen(path, flags, 0, allocator); | |
| 134 | const fd = try os.posixOpen(path, flags, 0, allocator); | |
| 135 | 135 | return openHandle(fd); |
| 136 | 136 | } else if (is_windows) { |
| 137 | const handle = %return os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ, | |
| 137 | const handle = try os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ, | |
| 138 | 138 | system.OPEN_EXISTING, system.FILE_ATTRIBUTE_NORMAL, allocator); |
| 139 | 139 | return openHandle(handle); |
| 140 | 140 | } else { |
| ... | ... | @@ -156,10 +156,10 @@ pub const File = struct { |
| 156 | 156 | pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) -> %File { |
| 157 | 157 | if (is_posix) { |
| 158 | 158 | const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC; |
| 159 | const fd = %return os.posixOpen(path, flags, mode, allocator); | |
| 159 | const fd = try os.posixOpen(path, flags, mode, allocator); | |
| 160 | 160 | return openHandle(fd); |
| 161 | 161 | } else if (is_windows) { |
| 162 | const handle = %return os.windowsOpen(path, system.GENERIC_WRITE, | |
| 162 | const handle = try os.windowsOpen(path, system.GENERIC_WRITE, | |
| 163 | 163 | system.FILE_SHARE_WRITE|system.FILE_SHARE_READ|system.FILE_SHARE_DELETE, |
| 164 | 164 | system.CREATE_ALWAYS, system.FILE_ATTRIBUTE_NORMAL, allocator); |
| 165 | 165 | return openHandle(handle); |
| ... | ... | @@ -190,7 +190,7 @@ pub const File = struct { |
| 190 | 190 | |
| 191 | 191 | pub fn seekForward(self: &File, amount: isize) -> %void { |
| 192 | 192 | switch (builtin.os) { |
| 193 | Os.linux, Os.darwin => { | |
| 193 | Os.linux, Os.macosx, Os.ios => { | |
| 194 | 194 | const result = system.lseek(self.handle, amount, system.SEEK_CUR); |
| 195 | 195 | const err = system.getErrno(result); |
| 196 | 196 | if (err > 0) { |
| ... | ... | @@ -210,7 +210,7 @@ pub const File = struct { |
| 210 | 210 | |
| 211 | 211 | pub fn seekTo(self: &File, pos: usize) -> %void { |
| 212 | 212 | switch (builtin.os) { |
| 213 | Os.linux, Os.darwin => { | |
| 213 | Os.linux, Os.macosx, Os.ios => { | |
| 214 | 214 | const result = system.lseek(self.handle, @bitCast(isize, pos), system.SEEK_SET); |
| 215 | 215 | const err = system.getErrno(result); |
| 216 | 216 | if (err > 0) { |
| ... | ... | @@ -230,7 +230,7 @@ pub const File = struct { |
| 230 | 230 | |
| 231 | 231 | pub fn getPos(self: &File) -> %usize { |
| 232 | 232 | switch (builtin.os) { |
| 233 | Os.linux, Os.darwin => { | |
| 233 | Os.linux, Os.macosx, Os.ios => { | |
| 234 | 234 | const result = system.lseek(self.handle, 0, system.SEEK_CUR); |
| 235 | 235 | const err = system.getErrno(result); |
| 236 | 236 | if (err > 0) { |
| ... | ... | @@ -322,9 +322,9 @@ pub const File = struct { |
| 322 | 322 | |
| 323 | 323 | fn write(self: &File, bytes: []const u8) -> %void { |
| 324 | 324 | if (is_posix) { |
| 325 | %return os.posixWrite(self.handle, bytes); | |
| 325 | try os.posixWrite(self.handle, bytes); | |
| 326 | 326 | } else if (is_windows) { |
| 327 | %return os.windowsWrite(self.handle, bytes); | |
| 327 | try os.windowsWrite(self.handle, bytes); | |
| 328 | 328 | } else { |
| 329 | 329 | @compileError("Unsupported OS"); |
| 330 | 330 | } |
| ... | ... | @@ -344,12 +344,12 @@ pub const InStream = struct { |
| 344 | 344 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and |
| 345 | 345 | /// the contents read from the stream are lost. |
| 346 | 346 | pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) -> %void { |
| 347 | %return buffer.resize(0); | |
| 347 | try buffer.resize(0); | |
| 348 | 348 | |
| 349 | 349 | var actual_buf_len: usize = 0; |
| 350 | 350 | while (true) { |
| 351 | 351 | const dest_slice = buffer.toSlice()[actual_buf_len..]; |
| 352 | const bytes_read = %return self.readFn(self, dest_slice); | |
| 352 | const bytes_read = try self.readFn(self, dest_slice); | |
| 353 | 353 | actual_buf_len += bytes_read; |
| 354 | 354 | |
| 355 | 355 | if (bytes_read != dest_slice.len) { |
| ... | ... | @@ -360,7 +360,7 @@ pub const InStream = struct { |
| 360 | 360 | const new_buf_size = math.min(max_size, actual_buf_len + os.page_size); |
| 361 | 361 | if (new_buf_size == actual_buf_len) |
| 362 | 362 | return error.StreamTooLong; |
| 363 | %return buffer.resize(new_buf_size); | |
| 363 | try buffer.resize(new_buf_size); | |
| 364 | 364 | } |
| 365 | 365 | } |
| 366 | 366 | |
| ... | ... | @@ -372,7 +372,7 @@ pub const InStream = struct { |
| 372 | 372 | var buf = Buffer.initNull(allocator); |
| 373 | 373 | defer buf.deinit(); |
| 374 | 374 | |
| 375 | %return self.readAllBuffer(&buf, max_size); | |
| 375 | try self.readAllBuffer(&buf, max_size); | |
| 376 | 376 | return buf.toOwnedSlice(); |
| 377 | 377 | } |
| 378 | 378 | |
| ... | ... | @@ -381,10 +381,10 @@ pub const InStream = struct { |
| 381 | 381 | /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents |
| 382 | 382 | /// read from the stream so far are lost. |
| 383 | 383 | pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) -> %void { |
| 384 | %return buf.resize(0); | |
| 384 | try buf.resize(0); | |
| 385 | 385 | |
| 386 | 386 | while (true) { |
| 387 | var byte: u8 = %return self.readByte(); | |
| 387 | var byte: u8 = try self.readByte(); | |
| 388 | 388 | |
| 389 | 389 | if (byte == delimiter) { |
| 390 | 390 | return; |
| ... | ... | @@ -394,7 +394,7 @@ pub const InStream = struct { |
| 394 | 394 | return error.StreamTooLong; |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | %return buf.appendByte(byte); | |
| 397 | try buf.appendByte(byte); | |
| 398 | 398 | } |
| 399 | 399 | } |
| 400 | 400 | |
| ... | ... | @@ -408,7 +408,7 @@ pub const InStream = struct { |
| 408 | 408 | var buf = Buffer.initNull(allocator); |
| 409 | 409 | defer buf.deinit(); |
| 410 | 410 | |
| 411 | %return self.readUntilDelimiterBuffer(self, &buf, delimiter, max_size); | |
| 411 | try self.readUntilDelimiterBuffer(self, &buf, delimiter, max_size); | |
| 412 | 412 | return buf.toOwnedSlice(); |
| 413 | 413 | } |
| 414 | 414 | |
| ... | ... | @@ -421,20 +421,20 @@ pub const InStream = struct { |
| 421 | 421 | |
| 422 | 422 | /// Same as `read` but end of stream returns `error.EndOfStream`. |
| 423 | 423 | pub fn readNoEof(self: &InStream, buf: []u8) -> %void { |
| 424 | const amt_read = %return self.read(buf); | |
| 424 | const amt_read = try self.read(buf); | |
| 425 | 425 | if (amt_read < buf.len) return error.EndOfStream; |
| 426 | 426 | } |
| 427 | 427 | |
| 428 | 428 | /// Reads 1 byte from the stream or returns `error.EndOfStream`. |
| 429 | 429 | pub fn readByte(self: &InStream) -> %u8 { |
| 430 | 430 | var result: [1]u8 = undefined; |
| 431 | %return self.readNoEof(result[0..]); | |
| 431 | try self.readNoEof(result[0..]); | |
| 432 | 432 | return result[0]; |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | 435 | /// Same as `readByte` except the returned byte is signed. |
| 436 | 436 | pub fn readByteSigned(self: &InStream) -> %i8 { |
| 437 | return @bitCast(i8, %return self.readByte()); | |
| 437 | return @bitCast(i8, try self.readByte()); | |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | 440 | pub fn readIntLe(self: &InStream, comptime T: type) -> %T { |
| ... | ... | @@ -447,7 +447,7 @@ pub const InStream = struct { |
| 447 | 447 | |
| 448 | 448 | pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T { |
| 449 | 449 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 450 | %return self.readNoEof(bytes[0..]); | |
| 450 | try self.readNoEof(bytes[0..]); | |
| 451 | 451 | return mem.readInt(bytes, T, endian); |
| 452 | 452 | } |
| 453 | 453 | |
| ... | ... | @@ -456,7 +456,7 @@ pub const InStream = struct { |
| 456 | 456 | assert(size <= 8); |
| 457 | 457 | var input_buf: [8]u8 = undefined; |
| 458 | 458 | const input_slice = input_buf[0..size]; |
| 459 | %return self.readNoEof(input_slice); | |
| 459 | try self.readNoEof(input_slice); | |
| 460 | 460 | return mem.readInt(input_slice, T, endian); |
| 461 | 461 | } |
| 462 | 462 | |
| ... | ... | @@ -483,7 +483,7 @@ pub const OutStream = struct { |
| 483 | 483 | const slice = (&byte)[0..1]; |
| 484 | 484 | var i: usize = 0; |
| 485 | 485 | while (i < n) : (i += 1) { |
| 486 | %return self.writeFn(self, slice); | |
| 486 | try self.writeFn(self, slice); | |
| 487 | 487 | } |
| 488 | 488 | } |
| 489 | 489 | }; |
| ... | ... | @@ -493,9 +493,9 @@ pub const OutStream = struct { |
| 493 | 493 | /// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned. |
| 494 | 494 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. |
| 495 | 495 | pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) -> %void { |
| 496 | var file = %return File.openWrite(path, allocator); | |
| 496 | var file = try File.openWrite(path, allocator); | |
| 497 | 497 | defer file.close(); |
| 498 | %return file.write(data); | |
| 498 | try file.write(data); | |
| 499 | 499 | } |
| 500 | 500 | |
| 501 | 501 | /// On success, caller owns returned buffer. |
| ... | ... | @@ -505,15 +505,15 @@ pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 { |
| 505 | 505 | /// On success, caller owns returned buffer. |
| 506 | 506 | /// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized. |
| 507 | 507 | pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 { |
| 508 | var file = %return File.openRead(path, allocator); | |
| 508 | var file = try File.openRead(path, allocator); | |
| 509 | 509 | defer file.close(); |
| 510 | 510 | |
| 511 | const size = %return file.getEndPos(); | |
| 512 | const buf = %return allocator.alloc(u8, size + extra_len); | |
| 511 | const size = try file.getEndPos(); | |
| 512 | const buf = try allocator.alloc(u8, size + extra_len); | |
| 513 | 513 | %defer allocator.free(buf); |
| 514 | 514 | |
| 515 | 515 | var adapter = FileInStream.init(&file); |
| 516 | %return adapter.stream.readNoEof(buf[0..size]); | |
| 516 | try adapter.stream.readNoEof(buf[0..size]); | |
| 517 | 517 | return buf; |
| 518 | 518 | } |
| 519 | 519 | |
| ... | ... | @@ -565,11 +565,11 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type { |
| 565 | 565 | // we can read more data from the unbuffered stream |
| 566 | 566 | if (dest_space < buffer_size) { |
| 567 | 567 | self.start_index = 0; |
| 568 | self.end_index = %return self.unbuffered_in_stream.read(self.buffer[0..]); | |
| 568 | self.end_index = try self.unbuffered_in_stream.read(self.buffer[0..]); | |
| 569 | 569 | } else { |
| 570 | 570 | // asking for so much data that buffering is actually less efficient. |
| 571 | 571 | // forward the request directly to the unbuffered stream |
| 572 | const amt_read = %return self.unbuffered_in_stream.read(dest[dest_index..]); | |
| 572 | const amt_read = try self.unbuffered_in_stream.read(dest[dest_index..]); | |
| 573 | 573 | return dest_index + amt_read; |
| 574 | 574 | } |
| 575 | 575 | } else { |
| ... | ... | @@ -616,7 +616,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { |
| 616 | 616 | if (self.index == 0) |
| 617 | 617 | return; |
| 618 | 618 | |
| 619 | %return self.unbuffered_out_stream.write(self.buffer[0..self.index]); | |
| 619 | try self.unbuffered_out_stream.write(self.buffer[0..self.index]); | |
| 620 | 620 | self.index = 0; |
| 621 | 621 | } |
| 622 | 622 | |
| ... | ... | @@ -624,7 +624,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { |
| 624 | 624 | const self = @fieldParentPtr(Self, "stream", out_stream); |
| 625 | 625 | |
| 626 | 626 | if (bytes.len >= self.buffer.len) { |
| 627 | %return self.flush(); | |
| 627 | try self.flush(); | |
| 628 | 628 | return self.unbuffered_out_stream.write(bytes); |
| 629 | 629 | } |
| 630 | 630 | var src_index: usize = 0; |
| ... | ... | @@ -636,7 +636,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type { |
| 636 | 636 | self.index += copy_amt; |
| 637 | 637 | assert(self.index <= self.buffer.len); |
| 638 | 638 | if (self.index == self.buffer.len) { |
| 639 | %return self.flush(); | |
| 639 | try self.flush(); | |
| 640 | 640 | } |
| 641 | 641 | src_index += copy_amt; |
| 642 | 642 | } |
std/linked_list.zig+1-1| ... | ... | @@ -188,7 +188,7 @@ pub fn LinkedList(comptime T: type) -> type { |
| 188 | 188 | /// Returns: |
| 189 | 189 | /// A pointer to the new node. |
| 190 | 190 | pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node { |
| 191 | var node = %return list.allocateNode(allocator); | |
| 191 | var node = try list.allocateNode(allocator); | |
| 192 | 192 | *node = Node.init(data); |
| 193 | 193 | return node; |
| 194 | 194 | } |
std/mem.zig+8-8| ... | ... | @@ -27,7 +27,7 @@ pub const Allocator = struct { |
| 27 | 27 | freeFn: fn (self: &Allocator, old_mem: []u8), |
| 28 | 28 | |
| 29 | 29 | fn create(self: &Allocator, comptime T: type) -> %&T { |
| 30 | const slice = %return self.alloc(T, 1); | |
| 30 | const slice = try self.alloc(T, 1); | |
| 31 | 31 | return &slice[0]; |
| 32 | 32 | } |
| 33 | 33 | |
| ... | ... | @@ -42,8 +42,8 @@ pub const Allocator = struct { |
| 42 | 42 | fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29, |
| 43 | 43 | n: usize) -> %[]align(alignment) T |
| 44 | 44 | { |
| 45 | const byte_count = %return math.mul(usize, @sizeOf(T), n); | |
| 46 | const byte_slice = %return self.allocFn(self, byte_count, alignment); | |
| 45 | const byte_count = try math.mul(usize, @sizeOf(T), n); | |
| 46 | const byte_slice = try self.allocFn(self, byte_count, alignment); | |
| 47 | 47 | // This loop should get optimized out in ReleaseFast mode |
| 48 | 48 | for (byte_slice) |*byte| { |
| 49 | 49 | *byte = undefined; |
| ... | ... | @@ -63,8 +63,8 @@ pub const Allocator = struct { |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | const old_byte_slice = ([]u8)(old_mem); |
| 66 | const byte_count = %return math.mul(usize, @sizeOf(T), n); | |
| 67 | const byte_slice = %return self.reallocFn(self, old_byte_slice, byte_count, alignment); | |
| 66 | const byte_count = try math.mul(usize, @sizeOf(T), n); | |
| 67 | const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment); | |
| 68 | 68 | // This loop should get optimized out in ReleaseFast mode |
| 69 | 69 | for (byte_slice[old_byte_slice.len..]) |*byte| { |
| 70 | 70 | *byte = undefined; |
| ... | ... | @@ -142,7 +142,7 @@ pub const FixedBufferAllocator = struct { |
| 142 | 142 | if (new_size <= old_mem.len) { |
| 143 | 143 | return old_mem[0..new_size]; |
| 144 | 144 | } else { |
| 145 | const result = %return alloc(allocator, new_size, alignment); | |
| 145 | const result = try alloc(allocator, new_size, alignment); | |
| 146 | 146 | copy(u8, result, old_mem); |
| 147 | 147 | return result; |
| 148 | 148 | } |
| ... | ... | @@ -198,7 +198,7 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool { |
| 198 | 198 | |
| 199 | 199 | /// Copies ::m to newly allocated memory. Caller is responsible to free it. |
| 200 | 200 | pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T { |
| 201 | const new_buf = %return allocator.alloc(T, m.len); | |
| 201 | const new_buf = try allocator.alloc(T, m.len); | |
| 202 | 202 | copy(T, new_buf, m); |
| 203 | 203 | return new_buf; |
| 204 | 204 | } |
| ... | ... | @@ -425,7 +425,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 { |
| 425 | 425 | } |
| 426 | 426 | } |
| 427 | 427 | |
| 428 | const buf = %return allocator.alloc(u8, total_strings_len); | |
| 428 | const buf = try allocator.alloc(u8, total_strings_len); | |
| 429 | 429 | %defer allocator.free(buf); |
| 430 | 430 | |
| 431 | 431 | var buf_index: usize = 0; |
std/net.zig+1-1| ... | ... | @@ -133,7 +133,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection { |
| 133 | 133 | |
| 134 | 134 | pub fn connect(hostname: []const u8, port: u16) -> %Connection { |
| 135 | 135 | var addrs_buf: [1]Address = undefined; |
| 136 | const addrs_slice = %return lookup(hostname, addrs_buf[0..]); | |
| 136 | const addrs_slice = try lookup(hostname, addrs_buf[0..]); | |
| 137 | 137 | const main_addr = &addrs_slice[0]; |
| 138 | 138 | |
| 139 | 139 | return connectAddr(main_addr, port); |
std/os/child_process.zig+55-55| ... | ... | @@ -75,7 +75,7 @@ pub const ChildProcess = struct { |
| 75 | 75 | /// First argument in argv is the executable. |
| 76 | 76 | /// On success must call deinit. |
| 77 | 77 | pub fn init(argv: []const []const u8, allocator: &mem.Allocator) -> %&ChildProcess { |
| 78 | const child = %return allocator.create(ChildProcess); | |
| 78 | const child = try allocator.create(ChildProcess); | |
| 79 | 79 | %defer allocator.destroy(child); |
| 80 | 80 | |
| 81 | 81 | *child = ChildProcess { |
| ... | ... | @@ -104,7 +104,7 @@ pub const ChildProcess = struct { |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | 106 | pub fn setUserName(self: &ChildProcess, name: []const u8) -> %void { |
| 107 | const user_info = %return os.getUserInfo(name); | |
| 107 | const user_info = try os.getUserInfo(name); | |
| 108 | 108 | self.uid = user_info.uid; |
| 109 | 109 | self.gid = user_info.gid; |
| 110 | 110 | } |
| ... | ... | @@ -120,7 +120,7 @@ pub const ChildProcess = struct { |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | pub fn spawnAndWait(self: &ChildProcess) -> %Term { |
| 123 | %return self.spawn(); | |
| 123 | try self.spawn(); | |
| 124 | 124 | return self.wait(); |
| 125 | 125 | } |
| 126 | 126 | |
| ... | ... | @@ -200,7 +200,7 @@ pub const ChildProcess = struct { |
| 200 | 200 | child.cwd = cwd; |
| 201 | 201 | child.env_map = env_map; |
| 202 | 202 | |
| 203 | %return child.spawn(); | |
| 203 | try child.spawn(); | |
| 204 | 204 | |
| 205 | 205 | var stdout = Buffer.initNull(allocator); |
| 206 | 206 | var stderr = Buffer.initNull(allocator); |
| ... | ... | @@ -210,11 +210,11 @@ pub const ChildProcess = struct { |
| 210 | 210 | var stdout_file_in_stream = io.FileInStream.init(&??child.stdout); |
| 211 | 211 | var stderr_file_in_stream = io.FileInStream.init(&??child.stderr); |
| 212 | 212 | |
| 213 | %return stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); | |
| 214 | %return stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size); | |
| 213 | try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size); | |
| 214 | try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size); | |
| 215 | 215 | |
| 216 | 216 | return ExecResult { |
| 217 | .term = %return child.wait(), | |
| 217 | .term = try child.wait(), | |
| 218 | 218 | .stdout = stdout.toOwnedSlice(), |
| 219 | 219 | .stderr = stderr.toOwnedSlice(), |
| 220 | 220 | }; |
| ... | ... | @@ -226,7 +226,7 @@ pub const ChildProcess = struct { |
| 226 | 226 | return term; |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | %return self.waitUnwrappedWindows(); | |
| 229 | try self.waitUnwrappedWindows(); | |
| 230 | 230 | return ??self.term; |
| 231 | 231 | } |
| 232 | 232 | |
| ... | ... | @@ -308,8 +308,8 @@ pub const ChildProcess = struct { |
| 308 | 308 | // pid potentially wrote an error. This way we can do a blocking |
| 309 | 309 | // read on the error pipe and either get @maxValue(ErrInt) (no error) or |
| 310 | 310 | // an error code. |
| 311 | %return writeIntFd(self.err_pipe[1], @maxValue(ErrInt)); | |
| 312 | const err_int = %return readIntFd(self.err_pipe[0]); | |
| 311 | try writeIntFd(self.err_pipe[1], @maxValue(ErrInt)); | |
| 312 | const err_int = try readIntFd(self.err_pipe[0]); | |
| 313 | 313 | // Here we potentially return the fork child's error |
| 314 | 314 | // from the parent pid. |
| 315 | 315 | if (err_int != @maxValue(ErrInt)) { |
| ... | ... | @@ -335,18 +335,18 @@ pub const ChildProcess = struct { |
| 335 | 335 | // TODO atomically set a flag saying that we already did this |
| 336 | 336 | install_SIGCHLD_handler(); |
| 337 | 337 | |
| 338 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) %return makePipe() else undefined; | |
| 338 | const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined; | |
| 339 | 339 | %defer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; |
| 340 | 340 | |
| 341 | const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) %return makePipe() else undefined; | |
| 341 | const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined; | |
| 342 | 342 | %defer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); }; |
| 343 | 343 | |
| 344 | const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) %return makePipe() else undefined; | |
| 344 | const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined; | |
| 345 | 345 | %defer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; |
| 346 | 346 | |
| 347 | 347 | const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); |
| 348 | 348 | const dev_null_fd = if (any_ignore) |
| 349 | %return os.posixOpen("/dev/null", posix.O_RDWR, 0, null) | |
| 349 | try os.posixOpen("/dev/null", posix.O_RDWR, 0, null) | |
| 350 | 350 | else |
| 351 | 351 | undefined |
| 352 | 352 | ; |
| ... | ... | @@ -359,14 +359,14 @@ pub const ChildProcess = struct { |
| 359 | 359 | break :x env_map; |
| 360 | 360 | } else x: { |
| 361 | 361 | we_own_env_map = true; |
| 362 | env_map_owned = %return os.getEnvMap(self.allocator); | |
| 362 | env_map_owned = try os.getEnvMap(self.allocator); | |
| 363 | 363 | break :x &env_map_owned; |
| 364 | 364 | }; |
| 365 | 365 | defer { if (we_own_env_map) env_map_owned.deinit(); } |
| 366 | 366 | |
| 367 | 367 | // This pipe is used to communicate errors between the time of fork |
| 368 | 368 | // and execve from the child process to the parent process. |
| 369 | const err_pipe = %return makePipe(); | |
| 369 | const err_pipe = try makePipe(); | |
| 370 | 370 | %defer destroyPipe(err_pipe); |
| 371 | 371 | |
| 372 | 372 | block_SIGCHLD(); |
| ... | ... | @@ -383,27 +383,27 @@ pub const ChildProcess = struct { |
| 383 | 383 | // we are the child |
| 384 | 384 | restore_SIGCHLD(); |
| 385 | 385 | |
| 386 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) %% | |
| 386 | setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch | |
| 387 | 387 | |err| forkChildErrReport(err_pipe[1], err); |
| 388 | setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) %% | |
| 388 | setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch | |
| 389 | 389 | |err| forkChildErrReport(err_pipe[1], err); |
| 390 | setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %% | |
| 390 | setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch | |
| 391 | 391 | |err| forkChildErrReport(err_pipe[1], err); |
| 392 | 392 | |
| 393 | 393 | if (self.cwd) |cwd| { |
| 394 | os.changeCurDir(self.allocator, cwd) %% | |
| 394 | os.changeCurDir(self.allocator, cwd) catch | |
| 395 | 395 | |err| forkChildErrReport(err_pipe[1], err); |
| 396 | 396 | } |
| 397 | 397 | |
| 398 | 398 | if (self.gid) |gid| { |
| 399 | os.posix_setregid(gid, gid) %% |err| forkChildErrReport(err_pipe[1], err); | |
| 399 | os.posix_setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err); | |
| 400 | 400 | } |
| 401 | 401 | |
| 402 | 402 | if (self.uid) |uid| { |
| 403 | os.posix_setreuid(uid, uid) %% |err| forkChildErrReport(err_pipe[1], err); | |
| 403 | os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err); | |
| 404 | 404 | } |
| 405 | 405 | |
| 406 | os.posixExecve(self.argv, env_map, self.allocator) %% | |
| 406 | os.posixExecve(self.argv, env_map, self.allocator) catch | |
| 407 | 407 | |err| forkChildErrReport(err_pipe[1], err); |
| 408 | 408 | } |
| 409 | 409 | |
| ... | ... | @@ -452,14 +452,14 @@ pub const ChildProcess = struct { |
| 452 | 452 | self.stderr_behavior == StdIo.Ignore); |
| 453 | 453 | |
| 454 | 454 | const nul_handle = if (any_ignore) |
| 455 | %return os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, | |
| 455 | try os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, | |
| 456 | 456 | windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null) |
| 457 | 457 | else |
| 458 | 458 | undefined |
| 459 | 459 | ; |
| 460 | 460 | defer { if (any_ignore) os.close(nul_handle); } |
| 461 | 461 | if (any_ignore) { |
| 462 | %return windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); | |
| 462 | try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); | |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | 465 | |
| ... | ... | @@ -467,7 +467,7 @@ pub const ChildProcess = struct { |
| 467 | 467 | var g_hChildStd_IN_Wr: ?windows.HANDLE = null; |
| 468 | 468 | switch (self.stdin_behavior) { |
| 469 | 469 | StdIo.Pipe => { |
| 470 | %return windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr); | |
| 470 | try windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr); | |
| 471 | 471 | }, |
| 472 | 472 | StdIo.Ignore => { |
| 473 | 473 | g_hChildStd_IN_Rd = nul_handle; |
| ... | ... | @@ -485,7 +485,7 @@ pub const ChildProcess = struct { |
| 485 | 485 | var g_hChildStd_OUT_Wr: ?windows.HANDLE = null; |
| 486 | 486 | switch (self.stdout_behavior) { |
| 487 | 487 | StdIo.Pipe => { |
| 488 | %return windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr); | |
| 488 | try windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr); | |
| 489 | 489 | }, |
| 490 | 490 | StdIo.Ignore => { |
| 491 | 491 | g_hChildStd_OUT_Wr = nul_handle; |
| ... | ... | @@ -503,7 +503,7 @@ pub const ChildProcess = struct { |
| 503 | 503 | var g_hChildStd_ERR_Wr: ?windows.HANDLE = null; |
| 504 | 504 | switch (self.stderr_behavior) { |
| 505 | 505 | StdIo.Pipe => { |
| 506 | %return windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr); | |
| 506 | try windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr); | |
| 507 | 507 | }, |
| 508 | 508 | StdIo.Ignore => { |
| 509 | 509 | g_hChildStd_ERR_Wr = nul_handle; |
| ... | ... | @@ -517,7 +517,7 @@ pub const ChildProcess = struct { |
| 517 | 517 | } |
| 518 | 518 | %defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); }; |
| 519 | 519 | |
| 520 | const cmd_line = %return windowsCreateCommandLine(self.allocator, self.argv); | |
| 520 | const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv); | |
| 521 | 521 | defer self.allocator.free(cmd_line); |
| 522 | 522 | |
| 523 | 523 | var siStartInfo = windows.STARTUPINFOA { |
| ... | ... | @@ -544,7 +544,7 @@ pub const ChildProcess = struct { |
| 544 | 544 | var piProcInfo: windows.PROCESS_INFORMATION = undefined; |
| 545 | 545 | |
| 546 | 546 | const cwd_slice = if (self.cwd) |cwd| |
| 547 | %return cstr.addNullByte(self.allocator, cwd) | |
| 547 | try cstr.addNullByte(self.allocator, cwd) | |
| 548 | 548 | else |
| 549 | 549 | null |
| 550 | 550 | ; |
| ... | ... | @@ -552,7 +552,7 @@ pub const ChildProcess = struct { |
| 552 | 552 | const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null; |
| 553 | 553 | |
| 554 | 554 | const maybe_envp_buf = if (self.env_map) |env_map| |
| 555 | %return os.createWindowsEnvBlock(self.allocator, env_map) | |
| 555 | try os.createWindowsEnvBlock(self.allocator, env_map) | |
| 556 | 556 | else |
| 557 | 557 | null |
| 558 | 558 | ; |
| ... | ... | @@ -563,27 +563,27 @@ pub const ChildProcess = struct { |
| 563 | 563 | // to match posix semantics |
| 564 | 564 | const app_name = x: { |
| 565 | 565 | if (self.cwd) |cwd| { |
| 566 | const resolved = %return os.path.resolve(self.allocator, cwd, self.argv[0]); | |
| 566 | const resolved = try os.path.resolve(self.allocator, cwd, self.argv[0]); | |
| 567 | 567 | defer self.allocator.free(resolved); |
| 568 | break :x %return cstr.addNullByte(self.allocator, resolved); | |
| 568 | break :x try cstr.addNullByte(self.allocator, resolved); | |
| 569 | 569 | } else { |
| 570 | break :x %return cstr.addNullByte(self.allocator, self.argv[0]); | |
| 570 | break :x try cstr.addNullByte(self.allocator, self.argv[0]); | |
| 571 | 571 | } |
| 572 | 572 | }; |
| 573 | 573 | defer self.allocator.free(app_name); |
| 574 | 574 | |
| 575 | 575 | windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, |
| 576 | &siStartInfo, &piProcInfo) %% |no_path_err| | |
| 576 | &siStartInfo, &piProcInfo) catch |no_path_err| | |
| 577 | 577 | { |
| 578 | 578 | if (no_path_err != error.FileNotFound) |
| 579 | 579 | return no_path_err; |
| 580 | 580 | |
| 581 | const PATH = %return os.getEnvVarOwned(self.allocator, "PATH"); | |
| 581 | const PATH = try os.getEnvVarOwned(self.allocator, "PATH"); | |
| 582 | 582 | defer self.allocator.free(PATH); |
| 583 | 583 | |
| 584 | 584 | var it = mem.split(PATH, ";"); |
| 585 | 585 | while (it.next()) |search_path| { |
| 586 | const joined_path = %return os.path.join(self.allocator, search_path, app_name); | |
| 586 | const joined_path = try os.path.join(self.allocator, search_path, app_name); | |
| 587 | 587 | defer self.allocator.free(joined_path); |
| 588 | 588 | |
| 589 | 589 | if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, |
| ... | ... | @@ -625,10 +625,10 @@ pub const ChildProcess = struct { |
| 625 | 625 | |
| 626 | 626 | fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) -> %void { |
| 627 | 627 | switch (stdio) { |
| 628 | StdIo.Pipe => %return os.posixDup2(pipe_fd, std_fileno), | |
| 628 | StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno), | |
| 629 | 629 | StdIo.Close => os.close(std_fileno), |
| 630 | 630 | StdIo.Inherit => {}, |
| 631 | StdIo.Ignore => %return os.posixDup2(dev_null_fd, std_fileno), | |
| 631 | StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno), | |
| 632 | 632 | } |
| 633 | 633 | } |
| 634 | 634 | |
| ... | ... | @@ -656,35 +656,35 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ? |
| 656 | 656 | /// Caller must dealloc. |
| 657 | 657 | /// Guarantees a null byte at result[result.len]. |
| 658 | 658 | fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) -> %[]u8 { |
| 659 | var buf = %return Buffer.initSize(allocator, 0); | |
| 659 | var buf = try Buffer.initSize(allocator, 0); | |
| 660 | 660 | defer buf.deinit(); |
| 661 | 661 | |
| 662 | 662 | for (argv) |arg, arg_i| { |
| 663 | 663 | if (arg_i != 0) |
| 664 | %return buf.appendByte(' '); | |
| 664 | try buf.appendByte(' '); | |
| 665 | 665 | if (mem.indexOfAny(u8, arg, " \t\n\"") == null) { |
| 666 | %return buf.append(arg); | |
| 666 | try buf.append(arg); | |
| 667 | 667 | continue; |
| 668 | 668 | } |
| 669 | %return buf.appendByte('"'); | |
| 669 | try buf.appendByte('"'); | |
| 670 | 670 | var backslash_count: usize = 0; |
| 671 | 671 | for (arg) |byte| { |
| 672 | 672 | switch (byte) { |
| 673 | 673 | '\\' => backslash_count += 1, |
| 674 | 674 | '"' => { |
| 675 | %return buf.appendByteNTimes('\\', backslash_count * 2 + 1); | |
| 676 | %return buf.appendByte('"'); | |
| 675 | try buf.appendByteNTimes('\\', backslash_count * 2 + 1); | |
| 676 | try buf.appendByte('"'); | |
| 677 | 677 | backslash_count = 0; |
| 678 | 678 | }, |
| 679 | 679 | else => { |
| 680 | %return buf.appendByteNTimes('\\', backslash_count); | |
| 681 | %return buf.appendByte(byte); | |
| 680 | try buf.appendByteNTimes('\\', backslash_count); | |
| 681 | try buf.appendByte(byte); | |
| 682 | 682 | backslash_count = 0; |
| 683 | 683 | }, |
| 684 | 684 | } |
| 685 | 685 | } |
| 686 | %return buf.appendByteNTimes('\\', backslash_count * 2); | |
| 687 | %return buf.appendByte('"'); | |
| 686 | try buf.appendByteNTimes('\\', backslash_count * 2); | |
| 687 | try buf.appendByte('"'); | |
| 688 | 688 | } |
| 689 | 689 | |
| 690 | 690 | return buf.toOwnedSlice(); |
| ... | ... | @@ -721,9 +721,9 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D |
| 721 | 721 | fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void { |
| 722 | 722 | var rd_h: windows.HANDLE = undefined; |
| 723 | 723 | var wr_h: windows.HANDLE = undefined; |
| 724 | %return windowsMakePipe(&rd_h, &wr_h, sattr); | |
| 724 | try windowsMakePipe(&rd_h, &wr_h, sattr); | |
| 725 | 725 | %defer windowsDestroyPipe(rd_h, wr_h); |
| 726 | %return windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0); | |
| 726 | try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0); | |
| 727 | 727 | *rd = rd_h; |
| 728 | 728 | *wr = wr_h; |
| 729 | 729 | } |
| ... | ... | @@ -731,9 +731,9 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S |
| 731 | 731 | fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void { |
| 732 | 732 | var rd_h: windows.HANDLE = undefined; |
| 733 | 733 | var wr_h: windows.HANDLE = undefined; |
| 734 | %return windowsMakePipe(&rd_h, &wr_h, sattr); | |
| 734 | try windowsMakePipe(&rd_h, &wr_h, sattr); | |
| 735 | 735 | %defer windowsDestroyPipe(rd_h, wr_h); |
| 736 | %return windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0); | |
| 736 | try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0); | |
| 737 | 737 | *rd = rd_h; |
| 738 | 738 | *wr = wr_h; |
| 739 | 739 | } |
| ... | ... | @@ -767,12 +767,12 @@ const ErrInt = @IntType(false, @sizeOf(error) * 8); |
| 767 | 767 | fn writeIntFd(fd: i32, value: ErrInt) -> %void { |
| 768 | 768 | var bytes: [@sizeOf(ErrInt)]u8 = undefined; |
| 769 | 769 | mem.writeInt(bytes[0..], value, builtin.endian); |
| 770 | os.posixWrite(fd, bytes[0..]) %% return error.SystemResources; | |
| 770 | os.posixWrite(fd, bytes[0..]) catch return error.SystemResources; | |
| 771 | 771 | } |
| 772 | 772 | |
| 773 | 773 | fn readIntFd(fd: i32) -> %ErrInt { |
| 774 | 774 | var bytes: [@sizeOf(ErrInt)]u8 = undefined; |
| 775 | os.posixRead(fd, bytes[0..]) %% return error.SystemResources; | |
| 775 | os.posixRead(fd, bytes[0..]) catch return error.SystemResources; | |
| 776 | 776 | return mem.readInt(bytes[0..], ErrInt, builtin.endian); |
| 777 | 777 | } |
| 778 | 778 |
std/os/get_user_id.zig+3-3| ... | ... | @@ -11,7 +11,7 @@ pub const UserInfo = struct { |
| 11 | 11 | /// POSIX function which gets a uid from username. |
| 12 | 12 | pub fn getUserInfo(name: []const u8) -> %UserInfo { |
| 13 | 13 | return switch (builtin.os) { |
| 14 | Os.linux, Os.darwin, Os.macosx, Os.ios => posixGetUserInfo(name), | |
| 14 | Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name), | |
| 15 | 15 | else => @compileError("Unsupported OS"), |
| 16 | 16 | }; |
| 17 | 17 | } |
| ... | ... | @@ -31,7 +31,7 @@ error CorruptPasswordFile; |
| 31 | 31 | // like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`. |
| 32 | 32 | |
| 33 | 33 | pub fn posixGetUserInfo(name: []const u8) -> %UserInfo { |
| 34 | var in_stream = %return io.InStream.open("/etc/passwd", null); | |
| 34 | var in_stream = try io.InStream.open("/etc/passwd", null); | |
| 35 | 35 | defer in_stream.close(); |
| 36 | 36 | |
| 37 | 37 | var buf: [os.page_size]u8 = undefined; |
| ... | ... | @@ -41,7 +41,7 @@ pub fn posixGetUserInfo(name: []const u8) -> %UserInfo { |
| 41 | 41 | var gid: u32 = 0; |
| 42 | 42 | |
| 43 | 43 | while (true) { |
| 44 | const amt_read = %return in_stream.read(buf[0..]); | |
| 44 | const amt_read = try in_stream.read(buf[0..]); | |
| 45 | 45 | for (buf[0..amt_read]) |byte| { |
| 46 | 46 | switch (state) { |
| 47 | 47 | State.Start => switch (byte) { |
std/os/index.zig+81-79| ... | ... | @@ -7,9 +7,11 @@ const os = this; |
| 7 | 7 | pub const windows = @import("windows/index.zig"); |
| 8 | 8 | pub const darwin = @import("darwin.zig"); |
| 9 | 9 | pub const linux = @import("linux.zig"); |
| 10 | pub const zen = @import("zen.zig"); | |
| 10 | 11 | pub const posix = switch(builtin.os) { |
| 11 | 12 | Os.linux => linux, |
| 12 | Os.darwin, Os.macosx, Os.ios => darwin, | |
| 13 | Os.macosx, Os.ios => darwin, | |
| 14 | Os.zen => zen, | |
| 13 | 15 | else => @compileError("Unsupported OS"), |
| 14 | 16 | }; |
| 15 | 17 | |
| ... | ... | @@ -89,12 +91,12 @@ pub fn getRandomBytes(buf: []u8) -> %void { |
| 89 | 91 | } |
| 90 | 92 | return; |
| 91 | 93 | }, |
| 92 | Os.darwin, Os.macosx, Os.ios => { | |
| 93 | const fd = %return posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC, | |
| 94 | Os.macosx, Os.ios => { | |
| 95 | const fd = try posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC, | |
| 94 | 96 | 0, null); |
| 95 | 97 | defer close(fd); |
| 96 | 98 | |
| 97 | %return posixRead(fd, buf); | |
| 99 | try posixRead(fd, buf); | |
| 98 | 100 | }, |
| 99 | 101 | Os.windows => { |
| 100 | 102 | var hCryptProv: windows.HCRYPTPROV = undefined; |
| ... | ... | @@ -130,7 +132,7 @@ pub coldcc fn abort() -> noreturn { |
| 130 | 132 | c.abort(); |
| 131 | 133 | } |
| 132 | 134 | switch (builtin.os) { |
| 133 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | |
| 135 | Os.linux, Os.macosx, Os.ios => { | |
| 134 | 136 | _ = posix.raise(posix.SIGABRT); |
| 135 | 137 | _ = posix.raise(posix.SIGKILL); |
| 136 | 138 | while (true) {} |
| ... | ... | @@ -151,7 +153,7 @@ pub coldcc fn exit(status: i32) -> noreturn { |
| 151 | 153 | c.exit(status); |
| 152 | 154 | } |
| 153 | 155 | switch (builtin.os) { |
| 154 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | |
| 156 | Os.linux, Os.macosx, Os.ios => { | |
| 155 | 157 | posix.exit(status); |
| 156 | 158 | }, |
| 157 | 159 | Os.windows => { |
| ... | ... | @@ -254,7 +256,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al |
| 254 | 256 | if (file_path.len < stack_buf.len) { |
| 255 | 257 | path0 = stack_buf[0..file_path.len + 1]; |
| 256 | 258 | } else if (allocator) |a| { |
| 257 | path0 = %return a.alloc(u8, file_path.len + 1); | |
| 259 | path0 = try a.alloc(u8, file_path.len + 1); | |
| 258 | 260 | need_free = true; |
| 259 | 261 | } else { |
| 260 | 262 | return error.NameTooLong; |
| ... | ... | @@ -312,14 +314,14 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void { |
| 312 | 314 | |
| 313 | 315 | pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) -> %[]?&u8 { |
| 314 | 316 | const envp_count = env_map.count(); |
| 315 | const envp_buf = %return allocator.alloc(?&u8, envp_count + 1); | |
| 317 | const envp_buf = try allocator.alloc(?&u8, envp_count + 1); | |
| 316 | 318 | mem.set(?&u8, envp_buf, null); |
| 317 | 319 | %defer freeNullDelimitedEnvMap(allocator, envp_buf); |
| 318 | 320 | { |
| 319 | 321 | var it = env_map.iterator(); |
| 320 | 322 | var i: usize = 0; |
| 321 | 323 | while (it.next()) |pair| : (i += 1) { |
| 322 | const env_buf = %return allocator.alloc(u8, pair.key.len + pair.value.len + 2); | |
| 324 | const env_buf = try allocator.alloc(u8, pair.key.len + pair.value.len + 2); | |
| 323 | 325 | @memcpy(&env_buf[0], pair.key.ptr, pair.key.len); |
| 324 | 326 | env_buf[pair.key.len] = '='; |
| 325 | 327 | @memcpy(&env_buf[pair.key.len + 1], pair.value.ptr, pair.value.len); |
| ... | ... | @@ -349,7 +351,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) { |
| 349 | 351 | pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 350 | 352 | allocator: &Allocator) -> %void |
| 351 | 353 | { |
| 352 | const argv_buf = %return allocator.alloc(?&u8, argv.len + 1); | |
| 354 | const argv_buf = try allocator.alloc(?&u8, argv.len + 1); | |
| 353 | 355 | mem.set(?&u8, argv_buf, null); |
| 354 | 356 | defer { |
| 355 | 357 | for (argv_buf) |arg| { |
| ... | ... | @@ -359,7 +361,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 359 | 361 | allocator.free(argv_buf); |
| 360 | 362 | } |
| 361 | 363 | for (argv) |arg, i| { |
| 362 | const arg_buf = %return allocator.alloc(u8, arg.len + 1); | |
| 364 | const arg_buf = try allocator.alloc(u8, arg.len + 1); | |
| 363 | 365 | @memcpy(&arg_buf[0], arg.ptr, arg.len); |
| 364 | 366 | arg_buf[arg.len] = 0; |
| 365 | 367 | |
| ... | ... | @@ -367,7 +369,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 367 | 369 | } |
| 368 | 370 | argv_buf[argv.len] = null; |
| 369 | 371 | |
| 370 | const envp_buf = %return createNullDelimitedEnvMap(allocator, env_map); | |
| 372 | const envp_buf = try createNullDelimitedEnvMap(allocator, env_map); | |
| 371 | 373 | defer freeNullDelimitedEnvMap(allocator, envp_buf); |
| 372 | 374 | |
| 373 | 375 | const exe_path = argv[0]; |
| ... | ... | @@ -379,7 +381,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 379 | 381 | // PATH.len because it is >= the largest search_path |
| 380 | 382 | // +1 for the / to join the search path and exe_path |
| 381 | 383 | // +1 for the null terminating byte |
| 382 | const path_buf = %return allocator.alloc(u8, PATH.len + exe_path.len + 2); | |
| 384 | const path_buf = try allocator.alloc(u8, PATH.len + exe_path.len + 2); | |
| 383 | 385 | defer allocator.free(path_buf); |
| 384 | 386 | var it = mem.split(PATH, ":"); |
| 385 | 387 | var seen_eacces = false; |
| ... | ... | @@ -448,7 +450,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap { |
| 448 | 450 | |
| 449 | 451 | i += 1; // skip over null byte |
| 450 | 452 | |
| 451 | %return result.set(key, value); | |
| 453 | try result.set(key, value); | |
| 452 | 454 | } |
| 453 | 455 | } else { |
| 454 | 456 | for (posix_environ_raw) |ptr| { |
| ... | ... | @@ -460,7 +462,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap { |
| 460 | 462 | while (ptr[end_i] != 0) : (end_i += 1) {} |
| 461 | 463 | const value = ptr[line_i + 1..end_i]; |
| 462 | 464 | |
| 463 | %return result.set(key, value); | |
| 465 | try result.set(key, value); | |
| 464 | 466 | } |
| 465 | 467 | return result; |
| 466 | 468 | } |
| ... | ... | @@ -488,14 +490,14 @@ error EnvironmentVariableNotFound; |
| 488 | 490 | /// Caller must free returned memory. |
| 489 | 491 | pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 490 | 492 | if (is_windows) { |
| 491 | const key_with_null = %return cstr.addNullByte(allocator, key); | |
| 493 | const key_with_null = try cstr.addNullByte(allocator, key); | |
| 492 | 494 | defer allocator.free(key_with_null); |
| 493 | 495 | |
| 494 | var buf = %return allocator.alloc(u8, 256); | |
| 496 | var buf = try allocator.alloc(u8, 256); | |
| 495 | 497 | %defer allocator.free(buf); |
| 496 | 498 | |
| 497 | 499 | while (true) { |
| 498 | const windows_buf_len = %return math.cast(windows.DWORD, buf.len); | |
| 500 | const windows_buf_len = try math.cast(windows.DWORD, buf.len); | |
| 499 | 501 | const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len); |
| 500 | 502 | |
| 501 | 503 | if (result == 0) { |
| ... | ... | @@ -507,7 +509,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 507 | 509 | } |
| 508 | 510 | |
| 509 | 511 | if (result > buf.len) { |
| 510 | buf = %return allocator.realloc(u8, buf, result); | |
| 512 | buf = try allocator.realloc(u8, buf, result); | |
| 511 | 513 | continue; |
| 512 | 514 | } |
| 513 | 515 | |
| ... | ... | @@ -523,7 +525,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 { |
| 523 | 525 | pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 524 | 526 | switch (builtin.os) { |
| 525 | 527 | Os.windows => { |
| 526 | var buf = %return allocator.alloc(u8, 256); | |
| 528 | var buf = try allocator.alloc(u8, 256); | |
| 527 | 529 | %defer allocator.free(buf); |
| 528 | 530 | |
| 529 | 531 | while (true) { |
| ... | ... | @@ -537,7 +539,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 537 | 539 | } |
| 538 | 540 | |
| 539 | 541 | if (result > buf.len) { |
| 540 | buf = %return allocator.realloc(u8, buf, result); | |
| 542 | buf = try allocator.realloc(u8, buf, result); | |
| 541 | 543 | continue; |
| 542 | 544 | } |
| 543 | 545 | |
| ... | ... | @@ -545,12 +547,12 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { |
| 545 | 547 | } |
| 546 | 548 | }, |
| 547 | 549 | else => { |
| 548 | var buf = %return allocator.alloc(u8, 1024); | |
| 550 | var buf = try allocator.alloc(u8, 1024); | |
| 549 | 551 | %defer allocator.free(buf); |
| 550 | 552 | while (true) { |
| 551 | 553 | const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len)); |
| 552 | 554 | if (err == posix.ERANGE) { |
| 553 | buf = %return allocator.realloc(u8, buf, buf.len * 2); | |
| 555 | buf = try allocator.realloc(u8, buf, buf.len * 2); | |
| 554 | 556 | continue; |
| 555 | 557 | } else if (err > 0) { |
| 556 | 558 | return unexpectedErrorPosix(err); |
| ... | ... | @@ -576,9 +578,9 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con |
| 576 | 578 | } |
| 577 | 579 | |
| 578 | 580 | pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { |
| 579 | const existing_with_null = %return cstr.addNullByte(allocator, existing_path); | |
| 581 | const existing_with_null = try cstr.addNullByte(allocator, existing_path); | |
| 580 | 582 | defer allocator.free(existing_with_null); |
| 581 | const new_with_null = %return cstr.addNullByte(allocator, new_path); | |
| 583 | const new_with_null = try cstr.addNullByte(allocator, new_path); | |
| 582 | 584 | defer allocator.free(new_with_null); |
| 583 | 585 | |
| 584 | 586 | if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) { |
| ... | ... | @@ -590,7 +592,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path |
| 590 | 592 | } |
| 591 | 593 | |
| 592 | 594 | pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { |
| 593 | const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2); | |
| 595 | const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2); | |
| 594 | 596 | defer allocator.free(full_buf); |
| 595 | 597 | |
| 596 | 598 | const existing_buf = full_buf; |
| ... | ... | @@ -636,11 +638,11 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: |
| 636 | 638 | } |
| 637 | 639 | |
| 638 | 640 | var rand_buf: [12]u8 = undefined; |
| 639 | const tmp_path = %return allocator.alloc(u8, new_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); | |
| 641 | const tmp_path = try allocator.alloc(u8, new_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); | |
| 640 | 642 | defer allocator.free(tmp_path); |
| 641 | 643 | mem.copy(u8, tmp_path[0..], new_path); |
| 642 | 644 | while (true) { |
| 643 | %return getRandomBytes(rand_buf[0..]); | |
| 645 | try getRandomBytes(rand_buf[0..]); | |
| 644 | 646 | b64_fs_encoder.encode(tmp_path[new_path.len..], rand_buf); |
| 645 | 647 | if (symLink(allocator, existing_path, tmp_path)) { |
| 646 | 648 | return rename(allocator, tmp_path, new_path); |
| ... | ... | @@ -667,7 +669,7 @@ error FileNotFound; |
| 667 | 669 | error AccessDenied; |
| 668 | 670 | |
| 669 | 671 | pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void { |
| 670 | const buf = %return allocator.alloc(u8, file_path.len + 1); | |
| 672 | const buf = try allocator.alloc(u8, file_path.len + 1); | |
| 671 | 673 | defer allocator.free(buf); |
| 672 | 674 | |
| 673 | 675 | mem.copy(u8, buf, file_path); |
| ... | ... | @@ -685,7 +687,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void |
| 685 | 687 | } |
| 686 | 688 | |
| 687 | 689 | pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void { |
| 688 | const buf = %return allocator.alloc(u8, file_path.len + 1); | |
| 690 | const buf = try allocator.alloc(u8, file_path.len + 1); | |
| 689 | 691 | defer allocator.free(buf); |
| 690 | 692 | |
| 691 | 693 | mem.copy(u8, buf, file_path); |
| ... | ... | @@ -719,30 +721,30 @@ pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []con |
| 719 | 721 | /// Guaranteed to be atomic. |
| 720 | 722 | pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void { |
| 721 | 723 | var rand_buf: [12]u8 = undefined; |
| 722 | const tmp_path = %return allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); | |
| 724 | const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len)); | |
| 723 | 725 | defer allocator.free(tmp_path); |
| 724 | 726 | mem.copy(u8, tmp_path[0..], dest_path); |
| 725 | %return getRandomBytes(rand_buf[0..]); | |
| 727 | try getRandomBytes(rand_buf[0..]); | |
| 726 | 728 | b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf); |
| 727 | 729 | |
| 728 | var out_file = %return io.File.openWriteMode(tmp_path, mode, allocator); | |
| 730 | var out_file = try io.File.openWriteMode(tmp_path, mode, allocator); | |
| 729 | 731 | defer out_file.close(); |
| 730 | 732 | %defer _ = deleteFile(allocator, tmp_path); |
| 731 | 733 | |
| 732 | var in_file = %return io.File.openRead(source_path, allocator); | |
| 734 | var in_file = try io.File.openRead(source_path, allocator); | |
| 733 | 735 | defer in_file.close(); |
| 734 | 736 | |
| 735 | 737 | var buf: [page_size]u8 = undefined; |
| 736 | 738 | while (true) { |
| 737 | const amt = %return in_file.read(buf[0..]); | |
| 738 | %return out_file.write(buf[0..amt]); | |
| 739 | const amt = try in_file.read(buf[0..]); | |
| 740 | try out_file.write(buf[0..amt]); | |
| 739 | 741 | if (amt != buf.len) |
| 740 | 742 | return rename(allocator, tmp_path, dest_path); |
| 741 | 743 | } |
| 742 | 744 | } |
| 743 | 745 | |
| 744 | 746 | pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) -> %void { |
| 745 | const full_buf = %return allocator.alloc(u8, old_path.len + new_path.len + 2); | |
| 747 | const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2); | |
| 746 | 748 | defer allocator.free(full_buf); |
| 747 | 749 | |
| 748 | 750 | const old_buf = full_buf; |
| ... | ... | @@ -795,7 +797,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 795 | 797 | } |
| 796 | 798 | |
| 797 | 799 | pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 798 | const path_buf = %return cstr.addNullByte(allocator, dir_path); | |
| 800 | const path_buf = try cstr.addNullByte(allocator, dir_path); | |
| 799 | 801 | defer allocator.free(path_buf); |
| 800 | 802 | |
| 801 | 803 | if (windows.CreateDirectoryA(path_buf.ptr, null) == 0) { |
| ... | ... | @@ -809,7 +811,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 809 | 811 | } |
| 810 | 812 | |
| 811 | 813 | pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 812 | const path_buf = %return cstr.addNullByte(allocator, dir_path); | |
| 814 | const path_buf = try cstr.addNullByte(allocator, dir_path); | |
| 813 | 815 | defer allocator.free(path_buf); |
| 814 | 816 | |
| 815 | 817 | const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755)); |
| ... | ... | @@ -835,12 +837,12 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 835 | 837 | /// Calls makeDir recursively to make an entire path. Returns success if the path |
| 836 | 838 | /// already exists and is a directory. |
| 837 | 839 | pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { |
| 838 | const resolved_path = %return path.resolve(allocator, full_path); | |
| 840 | const resolved_path = try path.resolve(allocator, full_path); | |
| 839 | 841 | defer allocator.free(resolved_path); |
| 840 | 842 | |
| 841 | 843 | var end_index: usize = resolved_path.len; |
| 842 | 844 | while (true) { |
| 843 | makeDir(allocator, resolved_path[0..end_index]) %% |err| { | |
| 845 | makeDir(allocator, resolved_path[0..end_index]) catch |err| { | |
| 844 | 846 | if (err == error.PathAlreadyExists) { |
| 845 | 847 | // TODO stat the file and return an error if it's not a directory |
| 846 | 848 | // this is important because otherwise a dangling symlink |
| ... | ... | @@ -873,7 +875,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void { |
| 873 | 875 | /// Returns ::error.DirNotEmpty if the directory is not empty. |
| 874 | 876 | /// To delete a directory recursively, see ::deleteTree |
| 875 | 877 | pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 876 | const path_buf = %return allocator.alloc(u8, dir_path.len + 1); | |
| 878 | const path_buf = try allocator.alloc(u8, dir_path.len + 1); | |
| 877 | 879 | defer allocator.free(path_buf); |
| 878 | 880 | |
| 879 | 881 | mem.copy(u8, path_buf, dir_path); |
| ... | ... | @@ -913,7 +915,7 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void { |
| 913 | 915 | return err; |
| 914 | 916 | } |
| 915 | 917 | { |
| 916 | var dir = Dir.open(allocator, full_path) %% |err| { | |
| 918 | var dir = Dir.open(allocator, full_path) catch |err| { | |
| 917 | 919 | if (err == error.FileNotFound) |
| 918 | 920 | return; |
| 919 | 921 | if (err == error.NotDir) |
| ... | ... | @@ -925,14 +927,14 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void { |
| 925 | 927 | var full_entry_buf = ArrayList(u8).init(allocator); |
| 926 | 928 | defer full_entry_buf.deinit(); |
| 927 | 929 | |
| 928 | while (%return dir.next()) |entry| { | |
| 929 | %return full_entry_buf.resize(full_path.len + entry.name.len + 1); | |
| 930 | while (try dir.next()) |entry| { | |
| 931 | try full_entry_buf.resize(full_path.len + entry.name.len + 1); | |
| 930 | 932 | const full_entry_path = full_entry_buf.toSlice(); |
| 931 | 933 | mem.copy(u8, full_entry_path, full_path); |
| 932 | 934 | full_entry_path[full_path.len] = '/'; |
| 933 | 935 | mem.copy(u8, full_entry_path[full_path.len + 1..], entry.name); |
| 934 | 936 | |
| 935 | %return deleteTree(allocator, full_entry_path); | |
| 937 | try deleteTree(allocator, full_entry_path); | |
| 936 | 938 | } |
| 937 | 939 | } |
| 938 | 940 | return deleteDir(allocator, full_path); |
| ... | ... | @@ -971,7 +973,7 @@ pub const Dir = struct { |
| 971 | 973 | }; |
| 972 | 974 | |
| 973 | 975 | pub fn open(allocator: &Allocator, dir_path: []const u8) -> %Dir { |
| 974 | const fd = %return posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); | |
| 976 | const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); | |
| 975 | 977 | return Dir { |
| 976 | 978 | .allocator = allocator, |
| 977 | 979 | .fd = fd, |
| ... | ... | @@ -992,7 +994,7 @@ pub const Dir = struct { |
| 992 | 994 | start_over: while (true) { |
| 993 | 995 | if (self.index >= self.end_index) { |
| 994 | 996 | if (self.buf.len == 0) { |
| 995 | self.buf = %return self.allocator.alloc(u8, page_size); | |
| 997 | self.buf = try self.allocator.alloc(u8, page_size); | |
| 996 | 998 | } |
| 997 | 999 | |
| 998 | 1000 | while (true) { |
| ... | ... | @@ -1002,7 +1004,7 @@ pub const Dir = struct { |
| 1002 | 1004 | switch (err) { |
| 1003 | 1005 | posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, |
| 1004 | 1006 | posix.EINVAL => { |
| 1005 | self.buf = %return self.allocator.realloc(u8, self.buf, self.buf.len * 2); | |
| 1007 | self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2); | |
| 1006 | 1008 | continue; |
| 1007 | 1009 | }, |
| 1008 | 1010 | else => return unexpectedErrorPosix(err), |
| ... | ... | @@ -1046,7 +1048,7 @@ pub const Dir = struct { |
| 1046 | 1048 | }; |
| 1047 | 1049 | |
| 1048 | 1050 | pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 1049 | const path_buf = %return allocator.alloc(u8, dir_path.len + 1); | |
| 1051 | const path_buf = try allocator.alloc(u8, dir_path.len + 1); | |
| 1050 | 1052 | defer allocator.free(path_buf); |
| 1051 | 1053 | |
| 1052 | 1054 | mem.copy(u8, path_buf, dir_path); |
| ... | ... | @@ -1070,13 +1072,13 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { |
| 1070 | 1072 | |
| 1071 | 1073 | /// Read value of a symbolic link. |
| 1072 | 1074 | pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1073 | const path_buf = %return allocator.alloc(u8, pathname.len + 1); | |
| 1075 | const path_buf = try allocator.alloc(u8, pathname.len + 1); | |
| 1074 | 1076 | defer allocator.free(path_buf); |
| 1075 | 1077 | |
| 1076 | 1078 | mem.copy(u8, path_buf, pathname); |
| 1077 | 1079 | path_buf[pathname.len] = 0; |
| 1078 | 1080 | |
| 1079 | var result_buf = %return allocator.alloc(u8, 1024); | |
| 1081 | var result_buf = try allocator.alloc(u8, 1024); | |
| 1080 | 1082 | %defer allocator.free(result_buf); |
| 1081 | 1083 | while (true) { |
| 1082 | 1084 | const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len); |
| ... | ... | @@ -1095,7 +1097,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1095 | 1097 | }; |
| 1096 | 1098 | } |
| 1097 | 1099 | if (ret_val == result_buf.len) { |
| 1098 | result_buf = %return allocator.realloc(u8, result_buf, result_buf.len * 2); | |
| 1100 | result_buf = try allocator.realloc(u8, result_buf, result_buf.len * 2); | |
| 1099 | 1101 | continue; |
| 1100 | 1102 | } |
| 1101 | 1103 | return allocator.shrink(u8, result_buf, ret_val); |
| ... | ... | @@ -1104,7 +1106,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1104 | 1106 | |
| 1105 | 1107 | pub fn sleep(seconds: usize, nanoseconds: usize) { |
| 1106 | 1108 | switch(builtin.os) { |
| 1107 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | |
| 1109 | Os.linux, Os.macosx, Os.ios => { | |
| 1108 | 1110 | posixSleep(u63(seconds), u63(nanoseconds)); |
| 1109 | 1111 | }, |
| 1110 | 1112 | Os.windows => { |
| ... | ... | @@ -1318,7 +1320,7 @@ pub const ArgIteratorWindows = struct { |
| 1318 | 1320 | } |
| 1319 | 1321 | |
| 1320 | 1322 | fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) -> %[]u8 { |
| 1321 | var buf = %return Buffer.initSize(allocator, 0); | |
| 1323 | var buf = try Buffer.initSize(allocator, 0); | |
| 1322 | 1324 | defer buf.deinit(); |
| 1323 | 1325 | |
| 1324 | 1326 | var backslash_count: usize = 0; |
| ... | ... | @@ -1328,34 +1330,34 @@ pub const ArgIteratorWindows = struct { |
| 1328 | 1330 | 0 => return buf.toOwnedSlice(), |
| 1329 | 1331 | '"' => { |
| 1330 | 1332 | const quote_is_real = backslash_count % 2 == 0; |
| 1331 | %return self.emitBackslashes(&buf, backslash_count / 2); | |
| 1333 | try self.emitBackslashes(&buf, backslash_count / 2); | |
| 1332 | 1334 | backslash_count = 0; |
| 1333 | 1335 | |
| 1334 | 1336 | if (quote_is_real) { |
| 1335 | 1337 | self.seen_quote_count += 1; |
| 1336 | 1338 | if (self.seen_quote_count == self.quote_count and self.seen_quote_count % 2 == 1) { |
| 1337 | %return buf.appendByte('"'); | |
| 1339 | try buf.appendByte('"'); | |
| 1338 | 1340 | } |
| 1339 | 1341 | } else { |
| 1340 | %return buf.appendByte('"'); | |
| 1342 | try buf.appendByte('"'); | |
| 1341 | 1343 | } |
| 1342 | 1344 | }, |
| 1343 | 1345 | '\\' => { |
| 1344 | 1346 | backslash_count += 1; |
| 1345 | 1347 | }, |
| 1346 | 1348 | ' ', '\t' => { |
| 1347 | %return self.emitBackslashes(&buf, backslash_count); | |
| 1349 | try self.emitBackslashes(&buf, backslash_count); | |
| 1348 | 1350 | backslash_count = 0; |
| 1349 | 1351 | if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) { |
| 1350 | %return buf.appendByte(byte); | |
| 1352 | try buf.appendByte(byte); | |
| 1351 | 1353 | } else { |
| 1352 | 1354 | return buf.toOwnedSlice(); |
| 1353 | 1355 | } |
| 1354 | 1356 | }, |
| 1355 | 1357 | else => { |
| 1356 | %return self.emitBackslashes(&buf, backslash_count); | |
| 1358 | try self.emitBackslashes(&buf, backslash_count); | |
| 1357 | 1359 | backslash_count = 0; |
| 1358 | %return buf.appendByte(byte); | |
| 1360 | try buf.appendByte(byte); | |
| 1359 | 1361 | }, |
| 1360 | 1362 | } |
| 1361 | 1363 | } |
| ... | ... | @@ -1364,7 +1366,7 @@ pub const ArgIteratorWindows = struct { |
| 1364 | 1366 | fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void { |
| 1365 | 1367 | var i: usize = 0; |
| 1366 | 1368 | while (i < emit_count) : (i += 1) { |
| 1367 | %return buf.appendByte('\\'); | |
| 1369 | try buf.appendByte('\\'); | |
| 1368 | 1370 | } |
| 1369 | 1371 | } |
| 1370 | 1372 | |
| ... | ... | @@ -1428,24 +1430,24 @@ pub fn args() -> ArgIterator { |
| 1428 | 1430 | pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 { |
| 1429 | 1431 | // TODO refactor to only make 1 allocation. |
| 1430 | 1432 | var it = args(); |
| 1431 | var contents = %return Buffer.initSize(allocator, 0); | |
| 1433 | var contents = try Buffer.initSize(allocator, 0); | |
| 1432 | 1434 | defer contents.deinit(); |
| 1433 | 1435 | |
| 1434 | 1436 | var slice_list = ArrayList(usize).init(allocator); |
| 1435 | 1437 | defer slice_list.deinit(); |
| 1436 | 1438 | |
| 1437 | 1439 | while (it.next(allocator)) |arg_or_err| { |
| 1438 | const arg = %return arg_or_err; | |
| 1440 | const arg = try arg_or_err; | |
| 1439 | 1441 | defer allocator.free(arg); |
| 1440 | %return contents.append(arg); | |
| 1441 | %return slice_list.append(arg.len); | |
| 1442 | try contents.append(arg); | |
| 1443 | try slice_list.append(arg.len); | |
| 1442 | 1444 | } |
| 1443 | 1445 | |
| 1444 | 1446 | const contents_slice = contents.toSliceConst(); |
| 1445 | 1447 | const slice_sizes = slice_list.toSliceConst(); |
| 1446 | const slice_list_bytes = %return math.mul(usize, @sizeOf([]u8), slice_sizes.len); | |
| 1447 | const total_bytes = %return math.add(usize, slice_list_bytes, contents_slice.len); | |
| 1448 | const buf = %return allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes); | |
| 1448 | const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len); | |
| 1449 | const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len); | |
| 1450 | const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes); | |
| 1449 | 1451 | %defer allocator.free(buf); |
| 1450 | 1452 | |
| 1451 | 1453 | const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]); |
| ... | ... | @@ -1537,7 +1539,7 @@ pub fn openSelfExe() -> %io.File { |
| 1537 | 1539 | Os.linux => { |
| 1538 | 1540 | return io.File.openRead("/proc/self/exe", null); |
| 1539 | 1541 | }, |
| 1540 | Os.darwin => { | |
| 1542 | Os.macosx, Os.ios => { | |
| 1541 | 1543 | @panic("TODO: openSelfExe on Darwin"); |
| 1542 | 1544 | }, |
| 1543 | 1545 | else => @compileError("Unsupported OS"), |
| ... | ... | @@ -1558,10 +1560,10 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { |
| 1558 | 1560 | return readLink(allocator, "/proc/self/exe"); |
| 1559 | 1561 | }, |
| 1560 | 1562 | Os.windows => { |
| 1561 | var out_path = %return Buffer.initSize(allocator, 0xff); | |
| 1563 | var out_path = try Buffer.initSize(allocator, 0xff); | |
| 1562 | 1564 | %defer out_path.deinit(); |
| 1563 | 1565 | while (true) { |
| 1564 | const dword_len = %return math.cast(windows.DWORD, out_path.len()); | |
| 1566 | const dword_len = try math.cast(windows.DWORD, out_path.len()); | |
| 1565 | 1567 | const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len); |
| 1566 | 1568 | if (copied_amt <= 0) { |
| 1567 | 1569 | const err = windows.GetLastError(); |
| ... | ... | @@ -1574,14 +1576,14 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { |
| 1574 | 1576 | return out_path.toOwnedSlice(); |
| 1575 | 1577 | } |
| 1576 | 1578 | const new_len = (out_path.len() << 1) | 0b1; |
| 1577 | %return out_path.resize(new_len); | |
| 1579 | try out_path.resize(new_len); | |
| 1578 | 1580 | } |
| 1579 | 1581 | }, |
| 1580 | Os.darwin, Os.macosx, Os.ios => { | |
| 1582 | Os.macosx, Os.ios => { | |
| 1581 | 1583 | var u32_len: u32 = 0; |
| 1582 | 1584 | const ret1 = c._NSGetExecutablePath(undefined, &u32_len); |
| 1583 | 1585 | assert(ret1 != 0); |
| 1584 | const bytes = %return allocator.alloc(u8, u32_len); | |
| 1586 | const bytes = try allocator.alloc(u8, u32_len); | |
| 1585 | 1587 | %defer allocator.free(bytes); |
| 1586 | 1588 | const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len); |
| 1587 | 1589 | assert(ret2 == 0); |
| ... | ... | @@ -1600,13 +1602,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { |
| 1600 | 1602 | // the file path looks something like `/a/b/c/exe (deleted)` |
| 1601 | 1603 | // This path cannot be opened, but it's valid for determining the directory |
| 1602 | 1604 | // the executable was in when it was run. |
| 1603 | const full_exe_path = %return readLink(allocator, "/proc/self/exe"); | |
| 1605 | const full_exe_path = try readLink(allocator, "/proc/self/exe"); | |
| 1604 | 1606 | %defer allocator.free(full_exe_path); |
| 1605 | 1607 | const dir = path.dirname(full_exe_path); |
| 1606 | 1608 | return allocator.shrink(u8, full_exe_path, dir.len); |
| 1607 | 1609 | }, |
| 1608 | Os.windows, Os.darwin, Os.macosx, Os.ios => { | |
| 1609 | const self_exe_path = %return selfExePath(allocator); | |
| 1610 | Os.windows, Os.macosx, Os.ios => { | |
| 1611 | const self_exe_path = try selfExePath(allocator); | |
| 1610 | 1612 | %defer allocator.free(self_exe_path); |
| 1611 | 1613 | const dirname = os.path.dirname(self_exe_path); |
| 1612 | 1614 | return allocator.shrink(u8, self_exe_path, dirname.len); |
std/os/path.zig+23-23| ... | ... | @@ -412,13 +412,13 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 |
| 412 | 412 | if (have_abs_path) { |
| 413 | 413 | switch (have_drive_kind) { |
| 414 | 414 | WindowsPath.Kind.Drive => { |
| 415 | result = %return allocator.alloc(u8, max_size); | |
| 415 | result = try allocator.alloc(u8, max_size); | |
| 416 | 416 | |
| 417 | 417 | mem.copy(u8, result, result_disk_designator); |
| 418 | 418 | result_index += result_disk_designator.len; |
| 419 | 419 | }, |
| 420 | 420 | WindowsPath.Kind.NetworkShare => { |
| 421 | result = %return allocator.alloc(u8, max_size); | |
| 421 | result = try allocator.alloc(u8, max_size); | |
| 422 | 422 | var it = mem.split(paths[first_index], "/\\"); |
| 423 | 423 | const server_name = ??it.next(); |
| 424 | 424 | const other_name = ??it.next(); |
| ... | ... | @@ -438,10 +438,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 |
| 438 | 438 | }, |
| 439 | 439 | WindowsPath.Kind.None => { |
| 440 | 440 | assert(is_windows); // resolveWindows called on non windows can't use getCwd |
| 441 | const cwd = %return os.getCwd(allocator); | |
| 441 | const cwd = try os.getCwd(allocator); | |
| 442 | 442 | defer allocator.free(cwd); |
| 443 | 443 | const parsed_cwd = windowsParsePath(cwd); |
| 444 | result = %return allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1); | |
| 444 | result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1); | |
| 445 | 445 | mem.copy(u8, result, parsed_cwd.disk_designator); |
| 446 | 446 | result_index += parsed_cwd.disk_designator.len; |
| 447 | 447 | result_disk_designator = result[0..parsed_cwd.disk_designator.len]; |
| ... | ... | @@ -454,10 +454,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 |
| 454 | 454 | } else { |
| 455 | 455 | assert(is_windows); // resolveWindows called on non windows can't use getCwd |
| 456 | 456 | // TODO call get cwd for the result_disk_designator instead of the global one |
| 457 | const cwd = %return os.getCwd(allocator); | |
| 457 | const cwd = try os.getCwd(allocator); | |
| 458 | 458 | defer allocator.free(cwd); |
| 459 | 459 | |
| 460 | result = %return allocator.alloc(u8, max_size + cwd.len + 1); | |
| 460 | result = try allocator.alloc(u8, max_size + cwd.len + 1); | |
| 461 | 461 | |
| 462 | 462 | mem.copy(u8, result, cwd); |
| 463 | 463 | result_index += cwd.len; |
| ... | ... | @@ -542,12 +542,12 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 { |
| 542 | 542 | var result_index: usize = 0; |
| 543 | 543 | |
| 544 | 544 | if (have_abs) { |
| 545 | result = %return allocator.alloc(u8, max_size); | |
| 545 | result = try allocator.alloc(u8, max_size); | |
| 546 | 546 | } else { |
| 547 | 547 | assert(!is_windows); // resolvePosix called on windows can't use getCwd |
| 548 | const cwd = %return os.getCwd(allocator); | |
| 548 | const cwd = try os.getCwd(allocator); | |
| 549 | 549 | defer allocator.free(cwd); |
| 550 | result = %return allocator.alloc(u8, max_size + cwd.len + 1); | |
| 550 | result = try allocator.alloc(u8, max_size + cwd.len + 1); | |
| 551 | 551 | mem.copy(u8, result, cwd); |
| 552 | 552 | result_index += cwd.len; |
| 553 | 553 | } |
| ... | ... | @@ -899,11 +899,11 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u |
| 899 | 899 | } |
| 900 | 900 | |
| 901 | 901 | pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 { |
| 902 | const resolved_from = %return resolveWindows(allocator, [][]const u8{from}); | |
| 902 | const resolved_from = try resolveWindows(allocator, [][]const u8{from}); | |
| 903 | 903 | defer allocator.free(resolved_from); |
| 904 | 904 | |
| 905 | 905 | var clean_up_resolved_to = true; |
| 906 | const resolved_to = %return resolveWindows(allocator, [][]const u8{to}); | |
| 906 | const resolved_to = try resolveWindows(allocator, [][]const u8{to}); | |
| 907 | 907 | defer if (clean_up_resolved_to) allocator.free(resolved_to); |
| 908 | 908 | |
| 909 | 909 | const parsed_from = windowsParsePath(resolved_from); |
| ... | ... | @@ -942,7 +942,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) |
| 942 | 942 | up_count += 1; |
| 943 | 943 | } |
| 944 | 944 | const up_index_end = up_count * "..\\".len; |
| 945 | const result = %return allocator.alloc(u8, up_index_end + to_rest.len); | |
| 945 | const result = try allocator.alloc(u8, up_index_end + to_rest.len); | |
| 946 | 946 | %defer allocator.free(result); |
| 947 | 947 | |
| 948 | 948 | var result_index: usize = 0; |
| ... | ... | @@ -972,10 +972,10 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) |
| 972 | 972 | } |
| 973 | 973 | |
| 974 | 974 | pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 { |
| 975 | const resolved_from = %return resolvePosix(allocator, [][]const u8{from}); | |
| 975 | const resolved_from = try resolvePosix(allocator, [][]const u8{from}); | |
| 976 | 976 | defer allocator.free(resolved_from); |
| 977 | 977 | |
| 978 | const resolved_to = %return resolvePosix(allocator, [][]const u8{to}); | |
| 978 | const resolved_to = try resolvePosix(allocator, [][]const u8{to}); | |
| 979 | 979 | defer allocator.free(resolved_to); |
| 980 | 980 | |
| 981 | 981 | var from_it = mem.split(resolved_from, "/"); |
| ... | ... | @@ -992,7 +992,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> |
| 992 | 992 | up_count += 1; |
| 993 | 993 | } |
| 994 | 994 | const up_index_end = up_count * "../".len; |
| 995 | const result = %return allocator.alloc(u8, up_index_end + to_rest.len); | |
| 995 | const result = try allocator.alloc(u8, up_index_end + to_rest.len); | |
| 996 | 996 | %defer allocator.free(result); |
| 997 | 997 | |
| 998 | 998 | var result_index: usize = 0; |
| ... | ... | @@ -1080,7 +1080,7 @@ error InputOutput; |
| 1080 | 1080 | pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1081 | 1081 | switch (builtin.os) { |
| 1082 | 1082 | Os.windows => { |
| 1083 | const pathname_buf = %return allocator.alloc(u8, pathname.len + 1); | |
| 1083 | const pathname_buf = try allocator.alloc(u8, pathname.len + 1); | |
| 1084 | 1084 | defer allocator.free(pathname_buf); |
| 1085 | 1085 | |
| 1086 | 1086 | mem.copy(u8, pathname_buf, pathname); |
| ... | ... | @@ -1099,10 +1099,10 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1099 | 1099 | }; |
| 1100 | 1100 | } |
| 1101 | 1101 | defer os.close(h_file); |
| 1102 | var buf = %return allocator.alloc(u8, 256); | |
| 1102 | var buf = try allocator.alloc(u8, 256); | |
| 1103 | 1103 | %defer allocator.free(buf); |
| 1104 | 1104 | while (true) { |
| 1105 | const buf_len = math.cast(windows.DWORD, buf.len) %% return error.NameTooLong; | |
| 1105 | const buf_len = math.cast(windows.DWORD, buf.len) catch return error.NameTooLong; | |
| 1106 | 1106 | const result = windows.GetFinalPathNameByHandleA(h_file, buf.ptr, buf_len, windows.VOLUME_NAME_DOS); |
| 1107 | 1107 | |
| 1108 | 1108 | if (result == 0) { |
| ... | ... | @@ -1116,7 +1116,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1116 | 1116 | } |
| 1117 | 1117 | |
| 1118 | 1118 | if (result > buf.len) { |
| 1119 | buf = %return allocator.realloc(u8, buf, result); | |
| 1119 | buf = try allocator.realloc(u8, buf, result); | |
| 1120 | 1120 | continue; |
| 1121 | 1121 | } |
| 1122 | 1122 | |
| ... | ... | @@ -1137,13 +1137,13 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1137 | 1137 | return allocator.shrink(u8, buf, final_len); |
| 1138 | 1138 | } |
| 1139 | 1139 | }, |
| 1140 | Os.darwin, Os.macosx, Os.ios => { | |
| 1140 | Os.macosx, Os.ios => { | |
| 1141 | 1141 | // TODO instead of calling the libc function here, port the implementation |
| 1142 | 1142 | // to Zig, and then remove the NameTooLong error possibility. |
| 1143 | const pathname_buf = %return allocator.alloc(u8, pathname.len + 1); | |
| 1143 | const pathname_buf = try allocator.alloc(u8, pathname.len + 1); | |
| 1144 | 1144 | defer allocator.free(pathname_buf); |
| 1145 | 1145 | |
| 1146 | const result_buf = %return allocator.alloc(u8, posix.PATH_MAX); | |
| 1146 | const result_buf = try allocator.alloc(u8, posix.PATH_MAX); | |
| 1147 | 1147 | %defer allocator.free(result_buf); |
| 1148 | 1148 | |
| 1149 | 1149 | mem.copy(u8, pathname_buf, pathname); |
| ... | ... | @@ -1168,7 +1168,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { |
| 1168 | 1168 | return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr)); |
| 1169 | 1169 | }, |
| 1170 | 1170 | Os.linux => { |
| 1171 | const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | |
| 1171 | const fd = try os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | |
| 1172 | 1172 | defer os.close(fd); |
| 1173 | 1173 | |
| 1174 | 1174 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; |
std/os/windows/util.zig+4-4| ... | ... | @@ -93,7 +93,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m |
| 93 | 93 | if (file_path.len < stack_buf.len) { |
| 94 | 94 | path0 = stack_buf[0..file_path.len + 1]; |
| 95 | 95 | } else if (allocator) |a| { |
| 96 | path0 = %return a.alloc(u8, file_path.len + 1); | |
| 96 | path0 = try a.alloc(u8, file_path.len + 1); | |
| 97 | 97 | need_free = true; |
| 98 | 98 | } else { |
| 99 | 99 | return error.NameTooLong; |
| ... | ... | @@ -132,7 +132,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) |
| 132 | 132 | } |
| 133 | 133 | break :x bytes_needed; |
| 134 | 134 | }; |
| 135 | const result = %return allocator.alloc(u8, bytes_needed); | |
| 135 | const result = try allocator.alloc(u8, bytes_needed); | |
| 136 | 136 | %defer allocator.free(result); |
| 137 | 137 | |
| 138 | 138 | var it = env_map.iterator(); |
| ... | ... | @@ -153,7 +153,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) |
| 153 | 153 | |
| 154 | 154 | error DllNotFound; |
| 155 | 155 | pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) -> %windows.HMODULE { |
| 156 | const padded_buff = %return cstr.addNullByte(allocator, dll_path); | |
| 156 | const padded_buff = try cstr.addNullByte(allocator, dll_path); | |
| 157 | 157 | defer allocator.free(padded_buff); |
| 158 | 158 | return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound; |
| 159 | 159 | } |
| ... | ... | @@ -166,7 +166,7 @@ pub fn windowsUnloadDll(hModule: windows.HMODULE) { |
| 166 | 166 | test "InvalidDll" { |
| 167 | 167 | const DllName = "asdf.dll"; |
| 168 | 168 | const allocator = std.debug.global_allocator; |
| 169 | const handle = os.windowsLoadDll(allocator, DllName) %% |err| { | |
| 169 | const handle = os.windowsLoadDll(allocator, DllName) catch |err| { | |
| 170 | 170 | assert(err == error.DllNotFound); |
| 171 | 171 | return; |
| 172 | 172 | }; |
std/os/zen.zig created+94| ... | ... | @@ -0,0 +1,94 @@ |
| 1 | ////////////////////////////// | |
| 2 | //// Reserved mailboxes //// | |
| 3 | ////////////////////////////// | |
| 4 | ||
| 5 | pub const MBOX_TERMINAL = 1; | |
| 6 | ||
| 7 | ||
| 8 | /////////////////////////// | |
| 9 | //// Syscall numbers //// | |
| 10 | /////////////////////////// | |
| 11 | ||
| 12 | pub const SYS_createMailbox = 0; | |
| 13 | pub const SYS_send = 1; | |
| 14 | pub const SYS_receive = 2; | |
| 15 | pub const SYS_map = 3; | |
| 16 | ||
| 17 | ||
| 18 | //////////////////// | |
| 19 | //// Syscalls //// | |
| 20 | //////////////////// | |
| 21 | ||
| 22 | pub fn createMailbox(id: u16) { | |
| 23 | _ = syscall1(SYS_createMailbox, id); | |
| 24 | } | |
| 25 | ||
| 26 | pub fn send(mailbox_id: u16, data: usize) { | |
| 27 | _ = syscall2(SYS_send, mailbox_id, data); | |
| 28 | } | |
| 29 | ||
| 30 | pub fn receive(mailbox_id: u16) -> usize { | |
| 31 | return syscall1(SYS_receive, mailbox_id); | |
| 32 | } | |
| 33 | ||
| 34 | pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) -> bool { | |
| 35 | return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0; | |
| 36 | } | |
| 37 | ||
| 38 | ||
| 39 | ///////////////////////// | |
| 40 | //// Syscall stubs //// | |
| 41 | ///////////////////////// | |
| 42 | ||
| 43 | pub inline fn syscall0(number: usize) -> usize { | |
| 44 | return asm volatile ("int $0x80" | |
| 45 | : [ret] "={eax}" (-> usize) | |
| 46 | : [number] "{eax}" (number)); | |
| 47 | } | |
| 48 | ||
| 49 | pub inline fn syscall1(number: usize, arg1: usize) -> usize { | |
| 50 | return asm volatile ("int $0x80" | |
| 51 | : [ret] "={eax}" (-> usize) | |
| 52 | : [number] "{eax}" (number), | |
| 53 | [arg1] "{ecx}" (arg1)); | |
| 54 | } | |
| 55 | ||
| 56 | pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize { | |
| 57 | return asm volatile ("int $0x80" | |
| 58 | : [ret] "={eax}" (-> usize) | |
| 59 | : [number] "{eax}" (number), | |
| 60 | [arg1] "{ecx}" (arg1), | |
| 61 | [arg2] "{edx}" (arg2)); | |
| 62 | } | |
| 63 | ||
| 64 | pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize { | |
| 65 | return asm volatile ("int $0x80" | |
| 66 | : [ret] "={eax}" (-> usize) | |
| 67 | : [number] "{eax}" (number), | |
| 68 | [arg1] "{ecx}" (arg1), | |
| 69 | [arg2] "{edx}" (arg2), | |
| 70 | [arg3] "{ebx}" (arg3)); | |
| 71 | } | |
| 72 | ||
| 73 | pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize { | |
| 74 | return asm volatile ("int $0x80" | |
| 75 | : [ret] "={eax}" (-> usize) | |
| 76 | : [number] "{eax}" (number), | |
| 77 | [arg1] "{ecx}" (arg1), | |
| 78 | [arg2] "{edx}" (arg2), | |
| 79 | [arg3] "{ebx}" (arg3), | |
| 80 | [arg4] "{esi}" (arg4)); | |
| 81 | } | |
| 82 | ||
| 83 | pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, | |
| 84 | arg4: usize, arg5: usize) -> usize | |
| 85 | { | |
| 86 | return asm volatile ("int $0x80" | |
| 87 | : [ret] "={eax}" (-> usize) | |
| 88 | : [number] "{eax}" (number), | |
| 89 | [arg1] "{ecx}" (arg1), | |
| 90 | [arg2] "{edx}" (arg2), | |
| 91 | [arg3] "{ebx}" (arg3), | |
| 92 | [arg4] "{esi}" (arg4), | |
| 93 | [arg5] "{edi}" (arg5)); | |
| 94 | } |
std/rand.zig+1-1| ... | ... | @@ -43,7 +43,7 @@ pub const Rand = struct { |
| 43 | 43 | } else { |
| 44 | 44 | var result: [@sizeOf(T)]u8 = undefined; |
| 45 | 45 | r.fillBytes(result[0..]); |
| 46 | return mem.readInt(result, T, false); | |
| 46 | return mem.readInt(result, T, builtin.Endian.Little); | |
| 47 | 47 | } |
| 48 | 48 | } |
| 49 | 49 |
std/special/bootstrap.zig+11-3| ... | ... | @@ -11,6 +11,8 @@ comptime { |
| 11 | 11 | const strong_linkage = builtin.GlobalLinkage.Strong; |
| 12 | 12 | if (builtin.link_libc) { |
| 13 | 13 | @export("main", main, strong_linkage); |
| 14 | } else if (builtin.os == builtin.Os.zen) { | |
| 15 | @export("main", zenMain, strong_linkage); | |
| 14 | 16 | } else if (builtin.os == builtin.Os.windows) { |
| 15 | 17 | @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); |
| 16 | 18 | } else { |
| ... | ... | @@ -18,6 +20,12 @@ comptime { |
| 18 | 20 | } |
| 19 | 21 | } |
| 20 | 22 | |
| 23 | extern fn zenMain() -> noreturn { | |
| 24 | // TODO: call exit. | |
| 25 | root.main() catch {}; | |
| 26 | while (true) {} | |
| 27 | } | |
| 28 | ||
| 21 | 29 | nakedcc fn _start() -> noreturn { |
| 22 | 30 | switch (builtin.arch) { |
| 23 | 31 | builtin.Arch.x86_64 => { |
| ... | ... | @@ -36,7 +44,7 @@ nakedcc fn _start() -> noreturn { |
| 36 | 44 | extern fn WinMainCRTStartup() -> noreturn { |
| 37 | 45 | @setAlignStack(16); |
| 38 | 46 | |
| 39 | root.main() %% std.os.windows.ExitProcess(1); | |
| 47 | root.main() catch std.os.windows.ExitProcess(1); | |
| 40 | 48 | std.os.windows.ExitProcess(0); |
| 41 | 49 | } |
| 42 | 50 | |
| ... | ... | @@ -44,7 +52,7 @@ fn posixCallMainAndExit() -> noreturn { |
| 44 | 52 | const argc = *argc_ptr; |
| 45 | 53 | const argv = @ptrCast(&&u8, &argc_ptr[1]); |
| 46 | 54 | const envp = @ptrCast(&?&u8, &argv[argc + 1]); |
| 47 | callMain(argc, argv, envp) %% std.os.posix.exit(1); | |
| 55 | callMain(argc, argv, envp) catch std.os.posix.exit(1); | |
| 48 | 56 | std.os.posix.exit(0); |
| 49 | 57 | } |
| 50 | 58 | |
| ... | ... | @@ -59,6 +67,6 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { |
| 59 | 67 | } |
| 60 | 68 | |
| 61 | 69 | extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { |
| 62 | callMain(usize(c_argc), c_argv, c_envp) %% return 1; | |
| 70 | callMain(usize(c_argc), c_argv, c_envp) catch return 1; | |
| 63 | 71 | return 0; |
| 64 | 72 | } |
std/special/build_runner.zig+25-25| ... | ... | @@ -23,15 +23,15 @@ pub fn main() -> %void { |
| 23 | 23 | // skip my own exe name |
| 24 | 24 | _ = arg_it.skip(); |
| 25 | 25 | |
| 26 | const zig_exe = %return unwrapArg(arg_it.next(allocator) ?? { | |
| 26 | const zig_exe = try unwrapArg(arg_it.next(allocator) ?? { | |
| 27 | 27 | warn("Expected first argument to be path to zig compiler\n"); |
| 28 | 28 | return error.InvalidArgs; |
| 29 | 29 | }); |
| 30 | const build_root = %return unwrapArg(arg_it.next(allocator) ?? { | |
| 30 | const build_root = try unwrapArg(arg_it.next(allocator) ?? { | |
| 31 | 31 | warn("Expected second argument to be build root directory path\n"); |
| 32 | 32 | return error.InvalidArgs; |
| 33 | 33 | }); |
| 34 | const cache_root = %return unwrapArg(arg_it.next(allocator) ?? { | |
| 34 | const cache_root = try unwrapArg(arg_it.next(allocator) ?? { | |
| 35 | 35 | warn("Expected third argument to be cache root directory path\n"); |
| 36 | 36 | return error.InvalidArgs; |
| 37 | 37 | }); |
| ... | ... | @@ -58,36 +58,36 @@ pub fn main() -> %void { |
| 58 | 58 | } else |err| err; |
| 59 | 59 | |
| 60 | 60 | while (arg_it.next(allocator)) |err_or_arg| { |
| 61 | const arg = %return unwrapArg(err_or_arg); | |
| 61 | const arg = try unwrapArg(err_or_arg); | |
| 62 | 62 | if (mem.startsWith(u8, arg, "-D")) { |
| 63 | 63 | const option_contents = arg[2..]; |
| 64 | 64 | if (option_contents.len == 0) { |
| 65 | 65 | warn("Expected option name after '-D'\n\n"); |
| 66 | return usageAndErr(&builder, false, %return stderr_stream); | |
| 66 | return usageAndErr(&builder, false, try stderr_stream); | |
| 67 | 67 | } |
| 68 | 68 | if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| { |
| 69 | 69 | const option_name = option_contents[0..name_end]; |
| 70 | 70 | const option_value = option_contents[name_end + 1..]; |
| 71 | 71 | if (builder.addUserInputOption(option_name, option_value)) |
| 72 | return usageAndErr(&builder, false, %return stderr_stream); | |
| 72 | return usageAndErr(&builder, false, try stderr_stream); | |
| 73 | 73 | } else { |
| 74 | 74 | if (builder.addUserInputFlag(option_contents)) |
| 75 | return usageAndErr(&builder, false, %return stderr_stream); | |
| 75 | return usageAndErr(&builder, false, try stderr_stream); | |
| 76 | 76 | } |
| 77 | 77 | } else if (mem.startsWith(u8, arg, "-")) { |
| 78 | 78 | if (mem.eql(u8, arg, "--verbose")) { |
| 79 | 79 | builder.verbose = true; |
| 80 | 80 | } else if (mem.eql(u8, arg, "--help")) { |
| 81 | return usage(&builder, false, %return stdout_stream); | |
| 81 | return usage(&builder, false, try stdout_stream); | |
| 82 | 82 | } else if (mem.eql(u8, arg, "--prefix")) { |
| 83 | prefix = %return unwrapArg(arg_it.next(allocator) ?? { | |
| 83 | prefix = try unwrapArg(arg_it.next(allocator) ?? { | |
| 84 | 84 | warn("Expected argument after --prefix\n\n"); |
| 85 | return usageAndErr(&builder, false, %return stderr_stream); | |
| 85 | return usageAndErr(&builder, false, try stderr_stream); | |
| 86 | 86 | }); |
| 87 | 87 | } else if (mem.eql(u8, arg, "--search-prefix")) { |
| 88 | const search_prefix = %return unwrapArg(arg_it.next(allocator) ?? { | |
| 88 | const search_prefix = try unwrapArg(arg_it.next(allocator) ?? { | |
| 89 | 89 | warn("Expected argument after --search-prefix\n\n"); |
| 90 | return usageAndErr(&builder, false, %return stderr_stream); | |
| 90 | return usageAndErr(&builder, false, try stderr_stream); | |
| 91 | 91 | }); |
| 92 | 92 | builder.addSearchPrefix(search_prefix); |
| 93 | 93 | } else if (mem.eql(u8, arg, "--verbose-tokenize")) { |
| ... | ... | @@ -104,7 +104,7 @@ pub fn main() -> %void { |
| 104 | 104 | builder.verbose_cimport = true; |
| 105 | 105 | } else { |
| 106 | 106 | warn("Unrecognized argument: {}\n\n", arg); |
| 107 | return usageAndErr(&builder, false, %return stderr_stream); | |
| 107 | return usageAndErr(&builder, false, try stderr_stream); | |
| 108 | 108 | } |
| 109 | 109 | } else { |
| 110 | 110 | %%targets.append(arg); |
| ... | ... | @@ -115,11 +115,11 @@ pub fn main() -> %void { |
| 115 | 115 | root.build(&builder); |
| 116 | 116 | |
| 117 | 117 | if (builder.validateUserInputDidItFail()) |
| 118 | return usageAndErr(&builder, true, %return stderr_stream); | |
| 118 | return usageAndErr(&builder, true, try stderr_stream); | |
| 119 | 119 | |
| 120 | builder.make(targets.toSliceConst()) %% |err| { | |
| 120 | builder.make(targets.toSliceConst()) catch |err| { | |
| 121 | 121 | if (err == error.InvalidStepName) { |
| 122 | return usageAndErr(&builder, true, %return stderr_stream); | |
| 122 | return usageAndErr(&builder, true, try stderr_stream); | |
| 123 | 123 | } |
| 124 | 124 | return err; |
| 125 | 125 | }; |
| ... | ... | @@ -133,7 +133,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | 135 | // This usage text has to be synchronized with src/main.cpp |
| 136 | %return out_stream.print( | |
| 136 | try out_stream.print( | |
| 137 | 137 | \\Usage: {} build [steps] [options] |
| 138 | 138 | \\ |
| 139 | 139 | \\Steps: |
| ... | ... | @@ -142,10 +142,10 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 142 | 142 | |
| 143 | 143 | const allocator = builder.allocator; |
| 144 | 144 | for (builder.top_level_steps.toSliceConst()) |top_level_step| { |
| 145 | %return out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description); | |
| 145 | try out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description); | |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | %return out_stream.write( | |
| 148 | try out_stream.write( | |
| 149 | 149 | \\ |
| 150 | 150 | \\General Options: |
| 151 | 151 | \\ --help Print this help and exit |
| ... | ... | @@ -158,17 +158,17 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 158 | 158 | ); |
| 159 | 159 | |
| 160 | 160 | if (builder.available_options_list.len == 0) { |
| 161 | %return out_stream.print(" (none)\n"); | |
| 161 | try out_stream.print(" (none)\n"); | |
| 162 | 162 | } else { |
| 163 | 163 | for (builder.available_options_list.toSliceConst()) |option| { |
| 164 | const name = %return fmt.allocPrint(allocator, | |
| 164 | const name = try fmt.allocPrint(allocator, | |
| 165 | 165 | " -D{}=[{}]", option.name, Builder.typeIdName(option.type_id)); |
| 166 | 166 | defer allocator.free(name); |
| 167 | %return out_stream.print("{s24} {}\n", name, option.description); | |
| 167 | try out_stream.print("{s24} {}\n", name, option.description); | |
| 168 | 168 | } |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | %return out_stream.write( | |
| 171 | try out_stream.write( | |
| 172 | 172 | \\ |
| 173 | 173 | \\Advanced Options: |
| 174 | 174 | \\ --build-file [file] Override path to build.zig |
| ... | ... | @@ -184,12 +184,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | 186 | fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> error { |
| 187 | usage(builder, already_ran_build, out_stream) %% {}; | |
| 187 | usage(builder, already_ran_build, out_stream) catch {}; | |
| 188 | 188 | return error.InvalidArgs; |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | fn unwrapArg(arg: %[]u8) -> %[]u8 { |
| 192 | return arg %% |err| { | |
| 192 | return arg catch |err| { | |
| 193 | 193 | warn("Unable to parse command line: {}\n", err); |
| 194 | 194 | return err; |
| 195 | 195 | }; |
std/special/panic.zig+8-4| ... | ... | @@ -6,9 +6,13 @@ |
| 6 | 6 | const builtin = @import("builtin"); |
| 7 | 7 | |
| 8 | 8 | pub coldcc fn panic(msg: []const u8) -> noreturn { |
| 9 | if (builtin.os == builtin.Os.freestanding) { | |
| 10 | while (true) {} | |
| 11 | } else { | |
| 12 | @import("std").debug.panic("{}", msg); | |
| 9 | switch (builtin.os) { | |
| 10 | // TODO: fix panic in zen. | |
| 11 | builtin.Os.freestanding, builtin.Os.zen => { | |
| 12 | while (true) {} | |
| 13 | }, | |
| 14 | else => { | |
| 15 | @import("std").debug.panic("{}", msg); | |
| 16 | }, | |
| 13 | 17 | } |
| 14 | 18 | } |
std/unicode.zig+1-1| ... | ... | @@ -162,7 +162,7 @@ fn testValid(bytes: []const u8, expected_codepoint: u32) { |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | fn testDecode(bytes: []const u8) -> %u32 { |
| 165 | const length = %return utf8ByteSequenceLength(bytes[0]); | |
| 165 | const length = try utf8ByteSequenceLength(bytes[0]); | |
| 166 | 166 | if (bytes.len < length) return error.UnexpectedEof; |
| 167 | 167 | std.debug.assert(bytes.len == length); |
| 168 | 168 | return utf8Decode(bytes); |
test/cases/defer.zig+1-1| ... | ... | @@ -18,7 +18,7 @@ test "mixing normal and error defers" { |
| 18 | 18 | assert(result[0] == 'c'); |
| 19 | 19 | assert(result[1] == 'a'); |
| 20 | 20 | |
| 21 | const ok = runSomeErrorDefers(false) %% |err| x: { | |
| 21 | const ok = runSomeErrorDefers(false) catch |err| x: { | |
| 22 | 22 | assert(err == error.FalseNotAllowed); |
| 23 | 23 | break :x true; |
| 24 | 24 | }; |
test/cases/error.zig+5-5| ... | ... | @@ -2,7 +2,7 @@ const assert = @import("std").debug.assert; |
| 2 | 2 | const mem = @import("std").mem; |
| 3 | 3 | |
| 4 | 4 | pub fn foo() -> %i32 { |
| 5 | const x = %return bar(); | |
| 5 | const x = try bar(); | |
| 6 | 6 | return x + 1; |
| 7 | 7 | } |
| 8 | 8 | |
| ... | ... | @@ -11,7 +11,7 @@ pub fn bar() -> %i32 { |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | pub fn baz() -> %i32 { |
| 14 | const y = foo() %% 1234; | |
| 14 | const y = foo() catch 1234; | |
| 15 | 15 | return y + 1; |
| 16 | 16 | } |
| 17 | 17 | |
| ... | ... | @@ -53,8 +53,8 @@ fn shouldBeNotEqual(a: error, b: error) { |
| 53 | 53 | |
| 54 | 54 | |
| 55 | 55 | test "error binary operator" { |
| 56 | const a = errBinaryOperatorG(true) %% 3; | |
| 57 | const b = errBinaryOperatorG(false) %% 3; | |
| 56 | const a = errBinaryOperatorG(true) catch 3; | |
| 57 | const b = errBinaryOperatorG(false) catch 3; | |
| 58 | 58 | assert(a == 3); |
| 59 | 59 | assert(b == 10); |
| 60 | 60 | } |
| ... | ... | @@ -77,7 +77,7 @@ test "error return in assignment" { |
| 77 | 77 | |
| 78 | 78 | fn doErrReturnInAssignment() -> %void { |
| 79 | 79 | var x : i32 = undefined; |
| 80 | x = %return makeANonErr(); | |
| 80 | x = try makeANonErr(); | |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | fn makeANonErr() -> %i32 { |
test/cases/ir_block_deps.zig+2-2| ... | ... | @@ -4,8 +4,8 @@ fn foo(id: u64) -> %i32 { |
| 4 | 4 | return switch (id) { |
| 5 | 5 | 1 => getErrInt(), |
| 6 | 6 | 2 => { |
| 7 | const size = %return getErrInt(); | |
| 8 | return %return getErrInt(); | |
| 7 | const size = try getErrInt(); | |
| 8 | return try getErrInt(); | |
| 9 | 9 | }, |
| 10 | 10 | else => error.ItBroke, |
| 11 | 11 | }; |
test/cases/misc.zig+31| ... | ... | @@ -577,3 +577,34 @@ test "implicit comptime while" { |
| 577 | 577 | @compileError("bad"); |
| 578 | 578 | } |
| 579 | 579 | } |
| 580 | ||
| 581 | test "struct inside function" { | |
| 582 | testStructInFn(); | |
| 583 | comptime testStructInFn(); | |
| 584 | } | |
| 585 | ||
| 586 | fn testStructInFn() { | |
| 587 | const BlockKind = u32; | |
| 588 | ||
| 589 | const Block = struct { | |
| 590 | kind: BlockKind, | |
| 591 | }; | |
| 592 | ||
| 593 | var block = Block { .kind = 1234 }; | |
| 594 | ||
| 595 | block.kind += 1; | |
| 596 | ||
| 597 | assert(block.kind == 1235); | |
| 598 | } | |
| 599 | ||
| 600 | fn fnThatClosesOverLocalConst() -> type { | |
| 601 | const c = 1; | |
| 602 | return struct { | |
| 603 | fn g() -> i32 { return c; } | |
| 604 | }; | |
| 605 | } | |
| 606 | ||
| 607 | test "function closes over local const" { | |
| 608 | const x = fnThatClosesOverLocalConst().g(); | |
| 609 | assert(x == 1); | |
| 610 | } |
test/cases/switch.zig+1-1| ... | ... | @@ -230,7 +230,7 @@ fn return_a_number() -> %i32 { |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | test "capture value of switch with all unreachable prongs" { |
| 233 | const x = return_a_number() %% |err| switch (err) { | |
| 233 | const x = return_a_number() catch |err| switch (err) { | |
| 234 | 234 | else => unreachable, |
| 235 | 235 | }; |
| 236 | 236 | assert(x == 1); |
test/cases/switch_prong_err_enum.zig+1-1| ... | ... | @@ -16,7 +16,7 @@ const FormValue = union(enum) { |
| 16 | 16 | |
| 17 | 17 | fn doThing(form_id: u64) -> %FormValue { |
| 18 | 18 | return switch (form_id) { |
| 19 | 17 => FormValue { .Address = %return readOnce() }, | |
| 19 | 17 => FormValue { .Address = try readOnce() }, | |
| 20 | 20 | else => error.InvalidDebugInfo, |
| 21 | 21 | }; |
| 22 | 22 | } |
test/compare_output.zig+10-10| ... | ... | @@ -395,14 +395,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 395 | 395 | cases.add("%defer and it fails", |
| 396 | 396 | \\const io = @import("std").io; |
| 397 | 397 | \\pub fn main() -> %void { |
| 398 | \\ do_test() %% return; | |
| 398 | \\ do_test() catch return; | |
| 399 | 399 | \\} |
| 400 | 400 | \\fn do_test() -> %void { |
| 401 | 401 | \\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream); |
| 402 | 402 | \\ %%stdout.print("before\n"); |
| 403 | 403 | \\ defer %%stdout.print("defer1\n"); |
| 404 | 404 | \\ %defer %%stdout.print("deferErr\n"); |
| 405 | \\ %return its_gonna_fail(); | |
| 405 | \\ try its_gonna_fail(); | |
| 406 | 406 | \\ defer %%stdout.print("defer3\n"); |
| 407 | 407 | \\ %%stdout.print("after\n"); |
| 408 | 408 | \\} |
| ... | ... | @@ -415,14 +415,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 415 | 415 | cases.add("%defer and it passes", |
| 416 | 416 | \\const io = @import("std").io; |
| 417 | 417 | \\pub fn main() -> %void { |
| 418 | \\ do_test() %% return; | |
| 418 | \\ do_test() catch return; | |
| 419 | 419 | \\} |
| 420 | 420 | \\fn do_test() -> %void { |
| 421 | 421 | \\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream); |
| 422 | 422 | \\ %%stdout.print("before\n"); |
| 423 | 423 | \\ defer %%stdout.print("defer1\n"); |
| 424 | 424 | \\ %defer %%stdout.print("deferErr\n"); |
| 425 | \\ %return its_gonna_pass(); | |
| 425 | \\ try its_gonna_pass(); | |
| 426 | 426 | \\ defer %%stdout.print("defer3\n"); |
| 427 | 427 | \\ %%stdout.print("after\n"); |
| 428 | 428 | \\} |
| ... | ... | @@ -454,14 +454,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 454 | 454 | \\ |
| 455 | 455 | \\pub fn main() -> %void { |
| 456 | 456 | \\ var args_it = os.args(); |
| 457 | \\ var stdout_file = %return io.getStdOut(); | |
| 457 | \\ var stdout_file = try io.getStdOut(); | |
| 458 | 458 | \\ var stdout_adapter = io.FileOutStream.init(&stdout_file); |
| 459 | 459 | \\ const stdout = &stdout_adapter.stream; |
| 460 | 460 | \\ var index: usize = 0; |
| 461 | 461 | \\ _ = args_it.skip(); |
| 462 | 462 | \\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) { |
| 463 | \\ const arg = %return arg_or_err; | |
| 464 | \\ %return stdout.print("{}: {}\n", index, arg); | |
| 463 | \\ const arg = try arg_or_err; | |
| 464 | \\ try stdout.print("{}: {}\n", index, arg); | |
| 465 | 465 | \\ } |
| 466 | 466 | \\} |
| 467 | 467 | , |
| ... | ... | @@ -495,14 +495,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 495 | 495 | \\ |
| 496 | 496 | \\pub fn main() -> %void { |
| 497 | 497 | \\ var args_it = os.args(); |
| 498 | \\ var stdout_file = %return io.getStdOut(); | |
| 498 | \\ var stdout_file = try io.getStdOut(); | |
| 499 | 499 | \\ var stdout_adapter = io.FileOutStream.init(&stdout_file); |
| 500 | 500 | \\ const stdout = &stdout_adapter.stream; |
| 501 | 501 | \\ var index: usize = 0; |
| 502 | 502 | \\ _ = args_it.skip(); |
| 503 | 503 | \\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) { |
| 504 | \\ const arg = %return arg_or_err; | |
| 505 | \\ %return stdout.print("{}: {}\n", index, arg); | |
| 504 | \\ const arg = try arg_or_err; | |
| 505 | \\ try stdout.print("{}: {}\n", index, arg); | |
| 506 | 506 | \\ } |
| 507 | 507 | \\} |
| 508 | 508 | , |
test/compile_errors.zig+16-4| ... | ... | @@ -1,6 +1,18 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: &tests.CompileErrorContext) { |
| 4 | cases.add("bad identifier in function with struct defined inside function which references local const", | |
| 5 | \\export fn entry() { | |
| 6 | \\ const BlockKind = u32; | |
| 7 | \\ | |
| 8 | \\ const Block = struct { | |
| 9 | \\ kind: BlockKind, | |
| 10 | \\ }; | |
| 11 | \\ | |
| 12 | \\ bogus; | |
| 13 | \\} | |
| 14 | , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'"); | |
| 15 | ||
| 4 | 16 | cases.add("labeled break not found", |
| 5 | 17 | \\export fn entry() { |
| 6 | 18 | \\ blah: while (true) { |
| ... | ... | @@ -1039,9 +1051,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1039 | 1051 | \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); } |
| 1040 | 1052 | , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'"); |
| 1041 | 1053 | |
| 1042 | cases.add("%return in function with non error return type", | |
| 1054 | cases.add("try in function with non error return type", | |
| 1043 | 1055 | \\export fn f() { |
| 1044 | \\ %return something(); | |
| 1056 | \\ try something(); | |
| 1045 | 1057 | \\} |
| 1046 | 1058 | \\fn something() -> %void { } |
| 1047 | 1059 | , |
| ... | ... | @@ -1276,9 +1288,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1276 | 1288 | |
| 1277 | 1289 | cases.add("return from defer expression", |
| 1278 | 1290 | \\pub fn testTrickyDefer() -> %void { |
| 1279 | \\ defer canFail() %% {}; | |
| 1291 | \\ defer canFail() catch {}; | |
| 1280 | 1292 | \\ |
| 1281 | \\ defer %return canFail(); | |
| 1293 | \\ defer try canFail(); | |
| 1282 | 1294 | \\ |
| 1283 | 1295 | \\ const a = maybeInt() ?? return; |
| 1284 | 1296 | \\} |
test/debug_safety.zig+5-2| ... | ... | @@ -221,11 +221,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 221 | 221 | |
| 222 | 222 | cases.addDebugSafety("unwrap error", |
| 223 | 223 | \\pub fn panic(message: []const u8) -> noreturn { |
| 224 | \\ @import("std").os.exit(126); | |
| 224 | \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) { | |
| 225 | \\ @import("std").os.exit(126); // good | |
| 226 | \\ } | |
| 227 | \\ @import("std").os.exit(0); // test failed | |
| 225 | 228 | \\} |
| 226 | 229 | \\error Whatever; |
| 227 | 230 | \\pub fn main() -> %void { |
| 228 | \\ %%bar(); | |
| 231 | \\ bar() catch unreachable; | |
| 229 | 232 | \\} |
| 230 | 233 | \\fn bar() -> %void { |
| 231 | 234 | \\ return error.Whatever; |
test/tests.zig+8-8| ... | ... | @@ -33,7 +33,7 @@ const test_targets = []TestTarget { |
| 33 | 33 | .environ = builtin.Environ.gnu, |
| 34 | 34 | }, |
| 35 | 35 | TestTarget { |
| 36 | .os = builtin.Os.darwin, | |
| 36 | .os = builtin.Os.macosx, | |
| 37 | 37 | .arch = builtin.Arch.x86_64, |
| 38 | 38 | .environ = builtin.Environ.unknown, |
| 39 | 39 | }, |
| ... | ... | @@ -259,7 +259,7 @@ pub const CompareOutputContext = struct { |
| 259 | 259 | child.stderr_behavior = StdIo.Pipe; |
| 260 | 260 | child.env_map = &b.env_map; |
| 261 | 261 | |
| 262 | child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | |
| 262 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | |
| 263 | 263 | |
| 264 | 264 | var stdout = Buffer.initNull(b.allocator); |
| 265 | 265 | var stderr = Buffer.initNull(b.allocator); |
| ... | ... | @@ -270,7 +270,7 @@ pub const CompareOutputContext = struct { |
| 270 | 270 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size); |
| 271 | 271 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size); |
| 272 | 272 | |
| 273 | const term = child.wait() %% |err| { | |
| 273 | const term = child.wait() catch |err| { | |
| 274 | 274 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| 275 | 275 | }; |
| 276 | 276 | switch (term) { |
| ... | ... | @@ -341,7 +341,7 @@ pub const CompareOutputContext = struct { |
| 341 | 341 | child.stdout_behavior = StdIo.Ignore; |
| 342 | 342 | child.stderr_behavior = StdIo.Ignore; |
| 343 | 343 | |
| 344 | const term = child.spawnAndWait() %% |err| { | |
| 344 | const term = child.spawnAndWait() catch |err| { | |
| 345 | 345 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| 346 | 346 | }; |
| 347 | 347 | |
| ... | ... | @@ -590,7 +590,7 @@ pub const CompileErrorContext = struct { |
| 590 | 590 | child.stdout_behavior = StdIo.Pipe; |
| 591 | 591 | child.stderr_behavior = StdIo.Pipe; |
| 592 | 592 | |
| 593 | child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); | |
| 593 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); | |
| 594 | 594 | |
| 595 | 595 | var stdout_buf = Buffer.initNull(b.allocator); |
| 596 | 596 | var stderr_buf = Buffer.initNull(b.allocator); |
| ... | ... | @@ -601,7 +601,7 @@ pub const CompileErrorContext = struct { |
| 601 | 601 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size); |
| 602 | 602 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size); |
| 603 | 603 | |
| 604 | const term = child.wait() %% |err| { | |
| 604 | const term = child.wait() catch |err| { | |
| 605 | 605 | debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err)); |
| 606 | 606 | }; |
| 607 | 607 | switch (term) { |
| ... | ... | @@ -862,7 +862,7 @@ pub const TranslateCContext = struct { |
| 862 | 862 | child.stdout_behavior = StdIo.Pipe; |
| 863 | 863 | child.stderr_behavior = StdIo.Pipe; |
| 864 | 864 | |
| 865 | child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); | |
| 865 | child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); | |
| 866 | 866 | |
| 867 | 867 | var stdout_buf = Buffer.initNull(b.allocator); |
| 868 | 868 | var stderr_buf = Buffer.initNull(b.allocator); |
| ... | ... | @@ -873,7 +873,7 @@ pub const TranslateCContext = struct { |
| 873 | 873 | %%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size); |
| 874 | 874 | %%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size); |
| 875 | 875 | |
| 876 | const term = child.wait() %% |err| { | |
| 876 | const term = child.wait() catch |err| { | |
| 877 | 877 | debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err)); |
| 878 | 878 | }; |
| 879 | 879 | switch (term) { |