authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2023-04-25 20:03:53+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-25 20:03:53+02:00
log015ea6fd6c0c0deacb42de237f737d208737e3ac
tree33f5e2d3acacc24e63f259ce5485fee28243ed44
parenta260fa8bf22b952e96b08c3f206756e1784ce870
parent8d88dcdc61c61e3410138f4402482131f5074a80
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge branch 'master' into autodoc-pkg-mod


66 files changed, 1713 insertions(+), 600 deletions(-)

doc/langref.html.in+65-15
...@@ -1422,7 +1422,8 @@ fn foo() i32 {...@@ -1422,7 +1422,8 @@ fn foo() i32 {
14221422
1423 {#header_open|Thread Local Variables#}1423 {#header_open|Thread Local Variables#}
1424 <p>A variable may be specified to be a thread-local variable using the1424 <p>A variable may be specified to be a thread-local variable using the
1425 {#syntax#}threadlocal{#endsyntax#} keyword:</p>1425 {#syntax#}threadlocal{#endsyntax#} keyword,
1426 which makes each thread work with a separate instance of the variable:</p>
1426 {#code_begin|test|test_thread_local_variables#}1427 {#code_begin|test|test_thread_local_variables#}
1427const std = @import("std");1428const std = @import("std");
1428const assert = std.debug.assert;1429const assert = std.debug.assert;
...@@ -4278,7 +4279,7 @@ const expectError = std.testing.expectError;...@@ -4278,7 +4279,7 @@ const expectError = std.testing.expectError;
4278fn isFieldOptional(comptime T: type, field_index: usize) !bool {4279fn isFieldOptional(comptime T: type, field_index: usize) !bool {
4279 const fields = @typeInfo(T).Struct.fields;4280 const fields = @typeInfo(T).Struct.fields;
4280 return switch (field_index) {4281 return switch (field_index) {
4281 // This prong is analyzed `fields.len - 1` times with `idx` being an4282 // This prong is analyzed `fields.len - 1` times with `idx` being a
4282 // unique comptime-known value each time.4283 // unique comptime-known value each time.
4283 inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .Optional,4284 inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .Optional,
4284 else => return error.IndexOutOfBounds,4285 else => return error.IndexOutOfBounds,
...@@ -4667,6 +4668,29 @@ test "for basics" {...@@ -4667,6 +4668,29 @@ test "for basics" {
4667 sum2 += @intCast(i32, i);4668 sum2 += @intCast(i32, i);
4668 }4669 }
4669 try expect(sum2 == 10);4670 try expect(sum2 == 10);
4671
4672 // To iterate over consecutive integers, use the range syntax.
4673 // Unbounded range is always a compile error.
4674 var sum3 : usize = 0;
4675 for (0..5) |i| {
4676 sum3 += i;
4677 }
4678 try expect(sum3 == 10);
4679}
4680
4681test "multi object for" {
4682 const items = [_]usize{ 1, 2, 3 };
4683 const items2 = [_]usize{ 4, 5, 6 };
4684 var count: usize = 0;
4685
4686 // Iterate over multiple objects.
4687 // All lengths must be equal at the start of the loop, otherwise detectable
4688 // illegal behavior occurs.
4689 for (items, items2) |i, j| {
4690 count += i + j;
4691 }
4692
4693 try expect(count == 21);
4670}4694}
46714695
4672test "for reference" {4696test "for reference" {
...@@ -4710,8 +4734,8 @@ const expect = std.testing.expect;...@@ -4710,8 +4734,8 @@ const expect = std.testing.expect;
47104734
4711test "nested break" {4735test "nested break" {
4712 var count: usize = 0;4736 var count: usize = 0;
4713 outer: for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {4737 outer: for (1..6) |_| {
4714 for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {4738 for (1..6) |_| {
4715 count += 1;4739 count += 1;
4716 break :outer;4740 break :outer;
4717 }4741 }
...@@ -4721,8 +4745,8 @@ test "nested break" {...@@ -4721,8 +4745,8 @@ test "nested break" {
47214745
4722test "nested continue" {4746test "nested continue" {
4723 var count: usize = 0;4747 var count: usize = 0;
4724 outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| {4748 outer: for (1..9) |_| {
4725 for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {4749 for (1..6) |_| {
4726 count += 1;4750 count += 1;
4727 continue :outer;4751 continue :outer;
4728 }4752 }
...@@ -8017,7 +8041,7 @@ pub const CallModifier = enum {...@@ -8017,7 +8041,7 @@ pub const CallModifier = enum {
8017 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>8041 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
8018 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>8042 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>
8019 <p>8043 <p>
8020 This function counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer.8044 Counts the number of most-significant (leading in a big-endian sense) zeroes in an integer - "count leading zeroes".
8021 </p>8045 </p>
8022 <p>8046 <p>
8023 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,8047 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,
...@@ -8167,7 +8191,7 @@ test "main" {...@@ -8167,7 +8191,7 @@ test "main" {
8167 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>8191 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
8168 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>8192 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>
8169 <p>8193 <p>
8170 This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.8194 Counts the number of least-significant (trailing in a big-endian sense) zeroes in an integer - "count trailing zeroes".
8171 </p>8195 </p>
8172 <p>8196 <p>
8173 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,8197 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,
...@@ -8553,16 +8577,27 @@ test "@hasDecl" {...@@ -8553,16 +8577,27 @@ test "@hasDecl" {
8553 </p>8577 </p>
8554 <ul>8578 <ul>
8555 <li>{#syntax#}@import("std"){#endsyntax#} - Zig Standard Library</li>8579 <li>{#syntax#}@import("std"){#endsyntax#} - Zig Standard Library</li>
8556 <li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information.8580 <li>{#syntax#}@import("builtin"){#endsyntax#} - Target-specific information
8557 The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.8581 The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.
8558 </li>8582 </li>
8559 <li>{#syntax#}@import("root"){#endsyntax#} - Points to the root source file.8583 <li>{#syntax#}@import("root"){#endsyntax#} - Root source file
8560 This is usually <code>src/main.zig</code> but it depends on what file is chosen to be built.8584 This is usually <code>src/main.zig</code> but depends on what file is built.
8561 </li>8585 </li>
8562 </ul>8586 </ul>
8563 {#see_also|Compile Variables|@embedFile#}8587 {#see_also|Compile Variables|@embedFile#}
8564 {#header_close#}8588 {#header_close#}
85658589
8590 {#header_open|@inComptime#}
8591 <pre>{#syntax#}@inComptime() bool{#endsyntax#}</pre>
8592 <p>
8593 Returns whether the builtin was run in a {#syntax#}comptime{#endsyntax#} context. The result is a compile-time constant.
8594 </p>
8595 <p>
8596 This can be used to provide alternative, comptime-friendly implementations of functions. It should not be used, for instance, to exclude certain functions from being evaluated at comptime.
8597 </p>
8598 {#see_also|comptime#}
8599 {#header_close#}
8600
8566 {#header_open|@intCast#}8601 {#header_open|@intCast#}
8567 <pre>{#syntax#}@intCast(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre>8602 <pre>{#syntax#}@intCast(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre>
8568 <p>8603 <p>
...@@ -8780,7 +8815,9 @@ test "@wasmMemoryGrow" {...@@ -8780,7 +8815,9 @@ test "@wasmMemoryGrow" {
8780 <pre>{#syntax#}@popCount(operand: anytype) anytype{#endsyntax#}</pre>8815 <pre>{#syntax#}@popCount(operand: anytype) anytype{#endsyntax#}</pre>
8781 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type.</p>8816 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type.</p>
8782 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>8817 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>
8783 <p>Counts the number of bits set in an integer.</p>8818 <p>
8819 Counts the number of bits set in an integer - "population count".
8820 </p>
8784 <p>8821 <p>
8785 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,8822 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,
8786 the return type is {#syntax#}comptime_int{#endsyntax#}.8823 the return type is {#syntax#}comptime_int{#endsyntax#}.
...@@ -8812,6 +8849,8 @@ test "@wasmMemoryGrow" {...@@ -8812,6 +8849,8 @@ test "@wasmMemoryGrow" {
8812pub const PrefetchOptions = struct {8849pub const PrefetchOptions = struct {
8813 /// Whether the prefetch should prepare for a read or a write.8850 /// Whether the prefetch should prepare for a read or a write.
8814 rw: Rw = .read,8851 rw: Rw = .read,
8852 /// The data's locality in an inclusive range from 0 to 3.
8853 ///
8815 /// 0 means no temporal locality. That is, the data can be immediately8854 /// 0 means no temporal locality. That is, the data can be immediately
8816 /// dropped from the cache after it is accessed.8855 /// dropped from the cache after it is accessed.
8817 ///8856 ///
...@@ -8821,12 +8860,12 @@ pub const PrefetchOptions = struct {...@@ -8821,12 +8860,12 @@ pub const PrefetchOptions = struct {
8821 /// The cache that the prefetch should be preformed on.8860 /// The cache that the prefetch should be preformed on.
8822 cache: Cache = .data,8861 cache: Cache = .data,
88238862
8824 pub const Rw = enum {8863 pub const Rw = enum(u1) {
8825 read,8864 read,
8826 write,8865 write,
8827 };8866 };
88288867
8829 pub const Cache = enum {8868 pub const Cache = enum(u1) {
8830 instruction,8869 instruction,
8831 data,8870 data,
8832 };8871 };
...@@ -10948,7 +10987,7 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke...@@ -10948,7 +10987,7 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke
10948 </p>10987 </p>
10949 <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>10988 <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>
10950 <ul>10989 <ul>
10951 <li>Supports all the syntax of the other two pointer types.</li>10990 <li>Supports all the syntax of the other two pointer types ({#syntax#}*T{#endsyntax#}) and ({#syntax#}[*]T{#endsyntax#}).</li>
10952 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.10991 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.
10953 When a C pointer is coerced to a non-optional pointer, safety-checked10992 When a C pointer is coerced to a non-optional pointer, safety-checked
10954 {#link|Undefined Behavior#} occurs if the address is 0.10993 {#link|Undefined Behavior#} occurs if the address is 0.
...@@ -11966,6 +12005,17 @@ fn readU32Be() u32 {}...@@ -11966,6 +12005,17 @@ fn readU32Be() u32 {}
11966 </ul>12005 </ul>
11967 </td>12006 </td>
11968 </tr>12007 </tr>
12008 <tr>
12009 <th scope="row">
12010 <pre>{#syntax#}noinline{#endsyntax#}</pre>
12011 </th>
12012 <td>
12013 {#syntax#}noinline{#endsyntax#} disallows function to be inlined in all call sites.
12014 <ul>
12015 <li>See also {#link|Functions#}</li>
12016 </ul>
12017 </td>
12018 </tr>
11969 <tr>12019 <tr>
11970 <th scope="row">12020 <th scope="row">
11971 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>12021 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>
lib/std/Build/Cache.zig+1-1
...@@ -184,7 +184,7 @@ pub const File = struct {...@@ -184,7 +184,7 @@ pub const File = struct {
184pub const HashHelper = struct {184pub const HashHelper = struct {
185 hasher: Hasher = hasher_init,185 hasher: Hasher = hasher_init,
186186
187 /// Record a slice of bytes as an dependency of the process being cached187 /// Record a slice of bytes as a dependency of the process being cached.
188 pub fn addBytes(hh: *HashHelper, bytes: []const u8) void {188 pub fn addBytes(hh: *HashHelper, bytes: []const u8) void {
189 hh.hasher.update(mem.asBytes(&bytes.len));189 hh.hasher.update(mem.asBytes(&bytes.len));
190 hh.hasher.update(bytes);190 hh.hasher.update(bytes);
lib/std/RingBuffer.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1//! This ring buffer stores read and write indices while being able to utilise1//! This ring buffer stores read and write indices while being able to utilise
2//! the full backing slice by incrementing the indices modulo twice the slice's2//! the full backing slice by incrementing the indices modulo twice the slice's
3//! length and reducing indices modulo the slice's length on slice access. This3//! length and reducing indices modulo the slice's length on slice access. This
4//! means that whether the ring buffer if full or empty can be distinguished by4//! means that whether the ring buffer is full or empty can be distinguished by
5//! looking at the difference between the read and write indices without adding5//! looking at the difference between the read and write indices without adding
6//! an extra boolean flag or having to reserve a slot in the buffer.6//! an extra boolean flag or having to reserve a slot in the buffer.
7//!7//!
lib/std/Uri.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1//! Implements URI parsing roughly adhering to <https://tools.ietf.org/html/rfc3986>.1//! Uniform Resource Identifier (URI) parsing roughly adhering to <https://tools.ietf.org/html/rfc3986>.
2//! Does not do perfect grammar and character class checking, but should be robust against URIs in the wild.2//! Does not do perfect grammar and character class checking, but should be robust against URIs in the wild.
33
4const Uri = @This();4const Uri = @This();
lib/std/array_list.zig+2
...@@ -221,6 +221,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -221,6 +221,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
221 /// Asserts the array has at least one item.221 /// Asserts the array has at least one item.
222 /// Invalidates pointers to end of list.222 /// Invalidates pointers to end of list.
223 /// This operation is O(N).223 /// This operation is O(N).
224 /// This preserves item order. Use `swapRemove` if order preservation is not important.
224 pub fn orderedRemove(self: *Self, i: usize) T {225 pub fn orderedRemove(self: *Self, i: usize) T {
225 const newlen = self.items.len - 1;226 const newlen = self.items.len - 1;
226 if (newlen == i) return self.pop();227 if (newlen == i) return self.pop();
...@@ -235,6 +236,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -235,6 +236,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
235 /// Removes the element at the specified index and returns it.236 /// Removes the element at the specified index and returns it.
236 /// The empty slot is filled from the end of the list.237 /// The empty slot is filled from the end of the list.
237 /// This operation is O(1).238 /// This operation is O(1).
239 /// This may not preserve item order. Use `orderedRemove` if you need to preserve order.
238 pub fn swapRemove(self: *Self, i: usize) T {240 pub fn swapRemove(self: *Self, i: usize) T {
239 if (self.items.len - 1 == i) return self.pop();241 if (self.items.len - 1 == i) return self.pop();
240242
lib/std/bit_set.zig+3-2
...@@ -35,9 +35,10 @@ const assert = std.debug.assert;...@@ -35,9 +35,10 @@ const assert = std.debug.assert;
35const Allocator = std.mem.Allocator;35const Allocator = std.mem.Allocator;
3636
37/// Returns the optimal static bit set type for the specified number37/// Returns the optimal static bit set type for the specified number
38/// of elements. The returned type will perform no allocations,38/// of elements: either `IntegerBitSet` or `ArrayBitSet`,
39/// both of which fulfill the same interface.
40/// The returned type will perform no allocations,
39/// can be copied by value, and does not require deinitialization.41/// can be copied by value, and does not require deinitialization.
40/// Both possible implementations fulfill the same interface.
41pub fn StaticBitSet(comptime size: usize) type {42pub fn StaticBitSet(comptime size: usize) type {
42 if (size <= @bitSizeOf(usize)) {43 if (size <= @bitSizeOf(usize)) {
43 return IntegerBitSet(size);44 return IntegerBitSet(size);
lib/std/builtin.zig+27
...@@ -144,22 +144,47 @@ pub const Mode = OptimizeMode;...@@ -144,22 +144,47 @@ pub const Mode = OptimizeMode;
144/// This data structure is used by the Zig language code generation and144/// This data structure is used by the Zig language code generation and
145/// therefore must be kept in sync with the compiler implementation.145/// therefore must be kept in sync with the compiler implementation.
146pub const CallingConvention = enum {146pub const CallingConvention = enum {
147 /// This is the default Zig calling convention used when not using `export` on `fn`
148 /// and no other calling convention is specified.
147 Unspecified,149 Unspecified,
150 /// Matches the C ABI for the target.
151 /// This is the default calling convention when using `export` on `fn`
152 /// and no other calling convention is specified.
148 C,153 C,
154 /// This makes a function not have any function prologue or epilogue,
155 /// making the function itself uncallable in regular Zig code.
156 /// This can be useful when integrating with assembly.
149 Naked,157 Naked,
158 /// Functions with this calling convention are called asynchronously,
159 /// as if called as `async function()`.
150 Async,160 Async,
161 /// Functions with this calling convention are inlined at all call sites.
151 Inline,162 Inline,
163 /// x86-only.
152 Interrupt,164 Interrupt,
153 Signal,165 Signal,
166 /// x86-only.
154 Stdcall,167 Stdcall,
168 /// x86-only.
155 Fastcall,169 Fastcall,
170 /// x86-only.
156 Vectorcall,171 Vectorcall,
172 /// x86-only.
157 Thiscall,173 Thiscall,
174 /// ARM Procedure Call Standard (obsolete)
175 /// ARM-only.
158 APCS,176 APCS,
177 /// ARM Architecture Procedure Call Standard (current standard)
178 /// ARM-only.
159 AAPCS,179 AAPCS,
180 /// ARM Architecture Procedure Call Standard Vector Floating-Point
181 /// ARM-only.
160 AAPCSVFP,182 AAPCSVFP,
183 /// x86-64-only.
161 SysV,184 SysV,
185 /// x86-64-only.
162 Win64,186 Win64,
187 /// AMD GPU, NVPTX, or SPIR-V kernel
163 Kernel,188 Kernel,
164};189};
165190
...@@ -716,6 +741,8 @@ pub const VaList = switch (builtin.cpu.arch) {...@@ -716,6 +741,8 @@ pub const VaList = switch (builtin.cpu.arch) {
716pub const PrefetchOptions = struct {741pub const PrefetchOptions = struct {
717 /// Whether the prefetch should prepare for a read or a write.742 /// Whether the prefetch should prepare for a read or a write.
718 rw: Rw = .read,743 rw: Rw = .read,
744 /// The data's locality in an inclusive range from 0 to 3.
745 ///
719 /// 0 means no temporal locality. That is, the data can be immediately746 /// 0 means no temporal locality. That is, the data can be immediately
720 /// dropped from the cache after it is accessed.747 /// dropped from the cache after it is accessed.
721 ///748 ///
lib/std/c/darwin.zig+8
...@@ -3846,3 +3846,11 @@ pub extern "c" fn os_signpost_interval_begin(log: os_log_t, signpos: os_signpost...@@ -3846,3 +3846,11 @@ pub extern "c" fn os_signpost_interval_begin(log: os_log_t, signpos: os_signpost
3846pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void;3846pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void;
3847pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t;3847pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t;
3848pub extern "c" fn os_signpost_enabled(log: os_log_t) bool;3848pub extern "c" fn os_signpost_enabled(log: os_log_t) bool;
3849
3850pub extern "c" fn proc_listpids(tpe: u32, tinfo: u32, buffer: ?*anyopaque, buffersize: c_int) c_int;
3851pub extern "c" fn proc_listallpids(buffer: ?*anyopaque, buffersize: c_int) c_int;
3852pub extern "c" fn proc_listpgrppids(pgrpid: pid_t, buffer: ?*anyopaque, buffersize: c_int) c_int;
3853pub extern "c" fn proc_listchildpids(ppid: pid_t, buffer: ?*anyopaque, buffersize: c_int) c_int;
3854pub extern "c" fn proc_pidinfo(pid: c_int, flavor: c_int, arg: u64, buffer: ?*anyopaque, buffersize: c_int) c_int;
3855pub extern "c" fn proc_name(pid: c_int, buffer: ?*anyopaque, buffersize: u32) c_int;
3856pub extern "c" fn proc_pidpath(pid: c_int, buffer: ?*anyopaque, buffersize: u32) c_int;
lib/std/c/dragonfly.zig+17
...@@ -1143,3 +1143,20 @@ pub const POLL = struct {...@@ -1143,3 +1143,20 @@ pub const POLL = struct {
1143 pub const HUP = 0x0010;1143 pub const HUP = 0x0010;
1144 pub const NVAL = 0x0020;1144 pub const NVAL = 0x0020;
1145};1145};
1146
1147pub const SIGEV = struct {
1148 pub const NONE = 0;
1149 pub const SIGNAL = 1;
1150 pub const THREAD = 2;
1151};
1152
1153pub const sigevent = extern struct {
1154 sigev_notify: c_int,
1155 __sigev_u: extern union {
1156 __sigev_signo: c_int,
1157 __sigev_notify_kqueue: c_int,
1158 __sigev_notify_attributes: ?*pthread_attr_t,
1159 },
1160 sigev_value: sigval,
1161 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1162};
lib/std/c/freebsd.zig+91-5
...@@ -29,6 +29,8 @@ pub const CPU_WHICH_TIDPID: cpuwhich_t = 8;...@@ -29,6 +29,8 @@ pub const CPU_WHICH_TIDPID: cpuwhich_t = 8;
29extern "c" fn __error() *c_int;29extern "c" fn __error() *c_int;
30pub const _errno = __error;30pub const _errno = __error;
3131
32pub extern "c" var malloc_options: [*:0]const u8;
33
32pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;34pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
33pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;35pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
34pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;36pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
...@@ -42,6 +44,7 @@ pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;...@@ -42,6 +44,7 @@ pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
4244
43pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;45pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
44pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;46pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;
47pub extern "c" fn reallocf(?*anyopaque, usize) ?*anyopaque;
4548
46pub extern "c" fn getpid() pid_t;49pub extern "c" fn getpid() pid_t;
4750
...@@ -50,6 +53,9 @@ pub extern "c" fn kinfo_getvmmap(pid: pid_t, cntp: *c_int) ?[*]kinfo_vmentry;...@@ -50,6 +53,9 @@ pub extern "c" fn kinfo_getvmmap(pid: pid_t, cntp: *c_int) ?[*]kinfo_vmentry;
5053
51pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int;54pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int;
52pub extern "c" fn cpuset_setaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *const cpuset_t) c_int;55pub extern "c" fn cpuset_setaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *const cpuset_t) c_int;
56pub extern "c" fn sched_getaffinity(pid: pid_t, cpusetsz: usize, cpuset: *cpuset_t) c_int;
57pub extern "c" fn sched_setaffinity(pid: pid_t, cpusetsz: usize, cpuset: *const cpuset_t) c_int;
58pub extern "c" fn sched_getcpu() c_int;
5359
54pub const sf_hdtr = extern struct {60pub const sf_hdtr = extern struct {
55 headers: [*]const iovec_const,61 headers: [*]const iovec_const,
...@@ -1102,6 +1108,11 @@ pub const DT = struct {...@@ -1102,6 +1108,11 @@ pub const DT = struct {
1102 pub const WHT = 14;1108 pub const WHT = 14;
1103};1109};
11041110
1111pub const accept_filter = extern struct {
1112 af_name: [16]u8,
1113 af_args: [240]u8,
1114};
1115
1105/// add event to kq (implies enable)1116/// add event to kq (implies enable)
1106pub const EV_ADD = 0x0001;1117pub const EV_ADD = 0x0001;
11071118
...@@ -1383,15 +1394,47 @@ pub const mcontext_t = switch (builtin.cpu.arch) {...@@ -1383,15 +1394,47 @@ pub const mcontext_t = switch (builtin.cpu.arch) {
1383 rflags: u64,1394 rflags: u64,
1384 rsp: u64,1395 rsp: u64,
1385 ss: u64,1396 ss: u64,
1386 len: u64,1397 len: c_long,
1387 fpformat: u64,1398 fpformat: c_long,
1388 ownedfp: u64,1399 ownedfp: c_long,
1389 fpstate: [64]u64 align(16),1400 fpstate: [64]c_long align(16),
1390 fsbase: u64,1401 fsbase: u64,
1391 gsbase: u64,1402 gsbase: u64,
1392 xfpustate: u64,1403 xfpustate: u64,
1393 xfpustate_len: u64,1404 xfpustate_len: u64,
1394 spare: [4]u64,1405 spare: [4]c_long,
1406 },
1407 .x86 => extern struct {
1408 onstack: u32,
1409 gs: u32,
1410 fs: u32,
1411 es: u32,
1412 ds: u32,
1413 edi: u32,
1414 esi: u32,
1415 ebp: u32,
1416 isp: u32,
1417 ebx: u32,
1418 edx: u32,
1419 ecx: u32,
1420 eax: u32,
1421 trapno: u32,
1422 err: u32,
1423 eip: u32,
1424 cs: u32,
1425 eflags: u32,
1426 esp: u32,
1427 ss: u32,
1428 len: c_int,
1429 fpformat: c_int,
1430 ownedfp: c_int,
1431 flags: u32,
1432 fpstate: [128]c_int align(16),
1433 fsbase: u32,
1434 gsbase: u32,
1435 xpustate: u32,
1436 xpustate_len: u32,
1437 spare2: [4]c_int,
1395 },1438 },
1396 .aarch64 => extern struct {1439 .aarch64 => extern struct {
1397 gpregs: extern struct {1440 gpregs: extern struct {
...@@ -2205,3 +2248,46 @@ pub const shm_largeconf = extern struct {...@@ -2205,3 +2248,46 @@ pub const shm_largeconf = extern struct {
2205pub extern "c" fn shm_create_largepage(path: [*:0]const u8, flags: c_int, psind: c_int, alloc_policy: c_int, mode: mode_t) c_int;2248pub extern "c" fn shm_create_largepage(path: [*:0]const u8, flags: c_int, psind: c_int, alloc_policy: c_int, mode: mode_t) c_int;
22062249
2207pub extern "c" fn elf_aux_info(aux: c_int, buf: ?*anyopaque, buflen: c_int) c_int;2250pub extern "c" fn elf_aux_info(aux: c_int, buf: ?*anyopaque, buflen: c_int) c_int;
2251
2252pub const lwpid = i32;
2253
2254pub const SIGEV = struct {
2255 pub const NONE = 0;
2256 pub const SIGNAL = 1;
2257 pub const THREAD = 2;
2258 pub const KEVENT = 3;
2259 pub const THREAD_ID = 4;
2260};
2261
2262pub const sigevent = extern struct {
2263 sigev_notify: c_int,
2264 sigev_signo: c_int,
2265 sigev_value: sigval,
2266 _sigev_un: extern union {
2267 _threadid: lwpid,
2268 _sigev_thread: extern struct {
2269 _function: ?*const fn (sigval) callconv(.C) void,
2270 _attribute: ?**pthread_attr_t,
2271 },
2272 _kevent_flags: c_ushort,
2273 __spare__: [8]c_long,
2274 },
2275};
2276
2277pub const MIN = struct {
2278 pub const INCORE = 0x1;
2279 pub const REFERENCED = 0x2;
2280 pub const MODIFIED = 0x4;
2281 pub const REFERENCED_OTHER = 0x8;
2282 pub const MODIFIED_OTHER = 0x10;
2283 pub const SUPER = 0x60;
2284 pub fn PSIND(i: u32) u32 {
2285 return (i << 5) & SUPER;
2286 }
2287};
2288
2289pub extern "c" fn mincore(
2290 addr: *align(std.mem.page_size) const anyopaque,
2291 length: usize,
2292 vec: [*]u8,
2293) c_int;
lib/std/c/haiku.zig+24-1
...@@ -5,11 +5,15 @@ const maxInt = std.math.maxInt;...@@ -5,11 +5,15 @@ const maxInt = std.math.maxInt;
5const iovec = std.os.iovec;5const iovec = std.os.iovec;
6const iovec_const = std.os.iovec_const;6const iovec_const = std.os.iovec_const;
77
8const status_t = i32;
9
8extern "c" fn _errnop() *c_int;10extern "c" fn _errnop() *c_int;
911
10pub const _errno = _errnop;12pub const _errno = _errnop;
1113
12pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;14pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) status_t;
15
16pub extern "c" fn find_path(codePointer: *const u8, baseDirectory: c_int, subPath: [*:0]const u8, pathBuffer: [*:0]u8, bufferSize: usize) status_t;
1317
14pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;18pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;
1519
...@@ -1038,3 +1042,22 @@ pub const termios = extern struct {...@@ -1038,3 +1042,22 @@ pub const termios = extern struct {
1038};1042};
10391043
1040pub const MSG_NOSIGNAL = 0x0800;1044pub const MSG_NOSIGNAL = 0x0800;
1045
1046pub const SIGEV = struct {
1047 pub const NONE = 0;
1048 pub const SIGNAL = 1;
1049 pub const THREAD = 2;
1050};
1051
1052pub const sigval = extern union {
1053 int: c_int,
1054 ptr: ?*anyopaque,
1055};
1056
1057pub const sigevent = extern struct {
1058 sigev_notify: c_int,
1059 sigev_signo: c_int,
1060 sigev_value: sigval,
1061 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1062 sigev_notify_attributes: ?*pthread_attr_t,
1063};
lib/std/c/netbsd.zig+19
...@@ -1633,3 +1633,22 @@ pub const POLL = struct {...@@ -1633,3 +1633,22 @@ pub const POLL = struct {
1633 pub const HUP = 0x0010;1633 pub const HUP = 0x0010;
1634 pub const NVAL = 0x0020;1634 pub const NVAL = 0x0020;
1635};1635};
1636
1637pub const SIGEV = struct {
1638 pub const NONE = 0;
1639 pub const SIGNAL = 1;
1640 pub const THREAD = 2;
1641};
1642
1643pub const sigval = extern union {
1644 int: c_int,
1645 ptr: ?*anyopaque,
1646};
1647
1648pub const sigevent = extern struct {
1649 sigev_notify: c_int,
1650 sigev_signo: c_int,
1651 sigev_value: sigval,
1652 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1653 sigev_notify_attributes: ?*pthread_attr_t,
1654};
lib/std/c/solaris.zig+19
...@@ -1927,3 +1927,22 @@ pub fn IOW(io_type: u8, nr: u8, comptime IOT: type) i32 {...@@ -1927,3 +1927,22 @@ pub fn IOW(io_type: u8, nr: u8, comptime IOT: type) i32 {
1927pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 {1927pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 {
1928 return ioImpl(.read_write, io_type, nr, IOT);1928 return ioImpl(.read_write, io_type, nr, IOT);
1929}1929}
1930
1931pub const SIGEV = struct {
1932 pub const NONE = 0;
1933 pub const SIGNAL = 1;
1934 pub const THREAD = 2;
1935};
1936
1937pub const sigval = extern union {
1938 int: c_int,
1939 ptr: ?*anyopaque,
1940};
1941
1942pub const sigevent = extern struct {
1943 sigev_notify: c_int,
1944 sigev_signo: c_int,
1945 sigev_value: sigval,
1946 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1947 sigev_notify_attributes: ?*pthread_attr_t,
1948};
lib/std/compress/zstandard.zig+1-1
...@@ -10,7 +10,7 @@ pub const decompress = @import("zstandard/decompress.zig");...@@ -10,7 +10,7 @@ pub const decompress = @import("zstandard/decompress.zig");
1010
11pub const DecompressStreamOptions = struct {11pub const DecompressStreamOptions = struct {
12 verify_checksum: bool = true,12 verify_checksum: bool = true,
13 window_size_max: usize = 1 << 23, // 8MiB default maximum window size,13 window_size_max: usize = 1 << 23, // 8MiB default maximum window size
14};14};
1515
16pub fn DecompressStream(16pub fn DecompressStream(
lib/std/compress/zstandard/decode/fse.zig+1-1
...@@ -21,7 +21,7 @@ pub fn decodeFseTable(...@@ -21,7 +21,7 @@ pub fn decodeFseTable(
21 var accumulated_probability: u16 = 0;21 var accumulated_probability: u16 = 0;
2222
23 while (accumulated_probability < total_probability) {23 while (accumulated_probability < total_probability) {
24 // WARNING: The RFC in poorly worded, and would suggest std.math.log2_int_ceil is correct here,24 // WARNING: The RFC is poorly worded, and would suggest std.math.log2_int_ceil is correct here,
25 // but power of two (remaining probabilities + 1) need max bits set to 1 more.25 // but power of two (remaining probabilities + 1) need max bits set to 1 more.
26 const max_bits = std.math.log2_int(u16, total_probability - accumulated_probability + 1) + 1;26 const max_bits = std.math.log2_int(u16, total_probability - accumulated_probability + 1) + 1;
27 const small = try bit_reader.readBitsNoEof(u16, max_bits - 1);27 const small = try bit_reader.readBitsNoEof(u16, max_bits - 1);
lib/std/crypto/sha2.zig+1-7
...@@ -71,12 +71,6 @@ const Sha256Params = Sha2Params32{...@@ -71,12 +71,6 @@ const Sha256Params = Sha2Params32{
7171
72const v4u32 = @Vector(4, u32);72const v4u32 = @Vector(4, u32);
7373
74// TODO: Remove once https://github.com/ziglang/zig/issues/868 is resolved.
75fn isComptime() bool {
76 var a: u8 = 0;
77 return @typeInfo(@TypeOf(.{a})).Struct.fields[0].is_comptime;
78}
79
80/// SHA-22474/// SHA-224
81pub const Sha224 = Sha2x32(Sha224Params);75pub const Sha224 = Sha2x32(Sha224Params);
8276
...@@ -203,7 +197,7 @@ fn Sha2x32(comptime params: Sha2Params32) type {...@@ -203,7 +197,7 @@ fn Sha2x32(comptime params: Sha2Params32) type {
203 s[i] = mem.readIntBig(u32, mem.asBytes(elem));197 s[i] = mem.readIntBig(u32, mem.asBytes(elem));
204 }198 }
205199
206 if (!isComptime()) {200 if (!@inComptime()) {
207 switch (builtin.cpu.arch) {201 switch (builtin.cpu.arch) {
208 .aarch64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) {202 .aarch64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) {
209 var x: v4u32 = d.s[0..4].*;203 var x: v4u32 = d.s[0..4].*;
lib/std/debug.zig+2
...@@ -651,6 +651,8 @@ pub fn writeCurrentStackTraceWindows(...@@ -651,6 +651,8 @@ pub fn writeCurrentStackTraceWindows(
651 }651 }
652}652}
653653
654/// Provides simple functionality for manipulating the terminal in some way,
655/// for debugging purposes, such as coloring text, etc.
654pub const TTY = struct {656pub const TTY = struct {
655 pub const Color = enum {657 pub const Color = enum {
656 Red,658 Red,
lib/std/elf.zig+88-5
...@@ -221,75 +221,138 @@ pub const DT_IA_64_NUM = 1;...@@ -221,75 +221,138 @@ pub const DT_IA_64_NUM = 1;
221221
222pub const DT_NIOS2_GP = 0x70000002;222pub const DT_NIOS2_GP = 0x70000002;
223223
224/// Program header table entry unused
224pub const PT_NULL = 0;225pub const PT_NULL = 0;
226/// Loadable program segment
225pub const PT_LOAD = 1;227pub const PT_LOAD = 1;
228/// Dynamic linking information
226pub const PT_DYNAMIC = 2;229pub const PT_DYNAMIC = 2;
230/// Program interpreter
227pub const PT_INTERP = 3;231pub const PT_INTERP = 3;
232/// Auxiliary information
228pub const PT_NOTE = 4;233pub const PT_NOTE = 4;
234/// Reserved
229pub const PT_SHLIB = 5;235pub const PT_SHLIB = 5;
236/// Entry for header table itself
230pub const PT_PHDR = 6;237pub const PT_PHDR = 6;
238/// Thread-local storage segment
231pub const PT_TLS = 7;239pub const PT_TLS = 7;
240/// Number of defined types
232pub const PT_NUM = 8;241pub const PT_NUM = 8;
242/// Start of OS-specific
233pub const PT_LOOS = 0x60000000;243pub const PT_LOOS = 0x60000000;
244/// GCC .eh_frame_hdr segment
234pub const PT_GNU_EH_FRAME = 0x6474e550;245pub const PT_GNU_EH_FRAME = 0x6474e550;
246/// Indicates stack executability
235pub const PT_GNU_STACK = 0x6474e551;247pub const PT_GNU_STACK = 0x6474e551;
248/// Read-only after relocation
236pub const PT_GNU_RELRO = 0x6474e552;249pub const PT_GNU_RELRO = 0x6474e552;
237pub const PT_LOSUNW = 0x6ffffffa;250pub const PT_LOSUNW = 0x6ffffffa;
251/// Sun specific segment
238pub const PT_SUNWBSS = 0x6ffffffa;252pub const PT_SUNWBSS = 0x6ffffffa;
253/// Stack segment
239pub const PT_SUNWSTACK = 0x6ffffffb;254pub const PT_SUNWSTACK = 0x6ffffffb;
240pub const PT_HISUNW = 0x6fffffff;255pub const PT_HISUNW = 0x6fffffff;
256/// End of OS-specific
241pub const PT_HIOS = 0x6fffffff;257pub const PT_HIOS = 0x6fffffff;
258/// Start of processor-specific
242pub const PT_LOPROC = 0x70000000;259pub const PT_LOPROC = 0x70000000;
260/// End of processor-specific
243pub const PT_HIPROC = 0x7fffffff;261pub const PT_HIPROC = 0x7fffffff;
244262
263/// Section header table entry unused
245pub const SHT_NULL = 0;264pub const SHT_NULL = 0;
265/// Program data
246pub const SHT_PROGBITS = 1;266pub const SHT_PROGBITS = 1;
267/// Symbol table
247pub const SHT_SYMTAB = 2;268pub const SHT_SYMTAB = 2;
269/// String table
248pub const SHT_STRTAB = 3;270pub const SHT_STRTAB = 3;
271/// Relocation entries with addends
249pub const SHT_RELA = 4;272pub const SHT_RELA = 4;
273/// Symbol hash table
250pub const SHT_HASH = 5;274pub const SHT_HASH = 5;
275/// Dynamic linking information
251pub const SHT_DYNAMIC = 6;276pub const SHT_DYNAMIC = 6;
277/// Notes
252pub const SHT_NOTE = 7;278pub const SHT_NOTE = 7;
279/// Program space with no data (bss)
253pub const SHT_NOBITS = 8;280pub const SHT_NOBITS = 8;
281/// Relocation entries, no addends
254pub const SHT_REL = 9;282pub const SHT_REL = 9;
283/// Reserved
255pub const SHT_SHLIB = 10;284pub const SHT_SHLIB = 10;
285/// Dynamic linker symbol table
256pub const SHT_DYNSYM = 11;286pub const SHT_DYNSYM = 11;
287/// Array of constructors
257pub const SHT_INIT_ARRAY = 14;288pub const SHT_INIT_ARRAY = 14;
289/// Array of destructors
258pub const SHT_FINI_ARRAY = 15;290pub const SHT_FINI_ARRAY = 15;
291/// Array of pre-constructors
259pub const SHT_PREINIT_ARRAY = 16;292pub const SHT_PREINIT_ARRAY = 16;
293/// Section group
260pub const SHT_GROUP = 17;294pub const SHT_GROUP = 17;
295/// Extended section indices
261pub const SHT_SYMTAB_SHNDX = 18;296pub const SHT_SYMTAB_SHNDX = 18;
297/// Start of OS-specific
262pub const SHT_LOOS = 0x60000000;298pub const SHT_LOOS = 0x60000000;
299/// End of OS-specific
263pub const SHT_HIOS = 0x6fffffff;300pub const SHT_HIOS = 0x6fffffff;
301/// Start of processor-specific
264pub const SHT_LOPROC = 0x70000000;302pub const SHT_LOPROC = 0x70000000;
303/// End of processor-specific
265pub const SHT_HIPROC = 0x7fffffff;304pub const SHT_HIPROC = 0x7fffffff;
305/// Start of application-specific
266pub const SHT_LOUSER = 0x80000000;306pub const SHT_LOUSER = 0x80000000;
307/// End of application-specific
267pub const SHT_HIUSER = 0xffffffff;308pub const SHT_HIUSER = 0xffffffff;
268309
310/// Local symbol
269pub const STB_LOCAL = 0;311pub const STB_LOCAL = 0;
312/// Global symbol
270pub const STB_GLOBAL = 1;313pub const STB_GLOBAL = 1;
314/// Weak symbol
271pub const STB_WEAK = 2;315pub const STB_WEAK = 2;
316/// Number of defined types
272pub const STB_NUM = 3;317pub const STB_NUM = 3;
318/// Start of OS-specific
273pub const STB_LOOS = 10;319pub const STB_LOOS = 10;
320/// Unique symbol
274pub const STB_GNU_UNIQUE = 10;321pub const STB_GNU_UNIQUE = 10;
322/// End of OS-specific
275pub const STB_HIOS = 12;323pub const STB_HIOS = 12;
324/// Start of processor-specific
276pub const STB_LOPROC = 13;325pub const STB_LOPROC = 13;
326/// End of processor-specific
277pub const STB_HIPROC = 15;327pub const STB_HIPROC = 15;
278328
279pub const STB_MIPS_SPLIT_COMMON = 13;329pub const STB_MIPS_SPLIT_COMMON = 13;
280330
331/// Symbol type is unspecified
281pub const STT_NOTYPE = 0;332pub const STT_NOTYPE = 0;
333/// Symbol is a data object
282pub const STT_OBJECT = 1;334pub const STT_OBJECT = 1;
335/// Symbol is a code object
283pub const STT_FUNC = 2;336pub const STT_FUNC = 2;
337/// Symbol associated with a section
284pub const STT_SECTION = 3;338pub const STT_SECTION = 3;
339/// Symbol's name is file name
285pub const STT_FILE = 4;340pub const STT_FILE = 4;
341/// Symbol is a common data object
286pub const STT_COMMON = 5;342pub const STT_COMMON = 5;
343/// Symbol is thread-local data object
287pub const STT_TLS = 6;344pub const STT_TLS = 6;
345/// Number of defined types
288pub const STT_NUM = 7;346pub const STT_NUM = 7;
347/// Start of OS-specific
289pub const STT_LOOS = 10;348pub const STT_LOOS = 10;
349/// Symbol is indirect code object
290pub const STT_GNU_IFUNC = 10;350pub const STT_GNU_IFUNC = 10;
351/// End of OS-specific
291pub const STT_HIOS = 12;352pub const STT_HIOS = 12;
353/// Start of processor-specific
292pub const STT_LOPROC = 13;354pub const STT_LOPROC = 13;
355/// End of processor-specific
293pub const STT_HIPROC = 15;356pub const STT_HIPROC = 15;
294357
295pub const STT_SPARC_REGISTER = 13;358pub const STT_SPARC_REGISTER = 13;
...@@ -656,6 +719,13 @@ pub const Elf32_Sym = extern struct {...@@ -656,6 +719,13 @@ pub const Elf32_Sym = extern struct {
656 st_info: u8,719 st_info: u8,
657 st_other: u8,720 st_other: u8,
658 st_shndx: Elf32_Section,721 st_shndx: Elf32_Section,
722
723 pub inline fn st_type(self: @This()) u4 {
724 return @truncate(u4, self.st_info);
725 }
726 pub inline fn st_bind(self: @This()) u4 {
727 return @truncate(u4, self.st_info >> 4);
728 }
659};729};
660pub const Elf64_Sym = extern struct {730pub const Elf64_Sym = extern struct {
661 st_name: Elf64_Word,731 st_name: Elf64_Word,
...@@ -664,6 +734,13 @@ pub const Elf64_Sym = extern struct {...@@ -664,6 +734,13 @@ pub const Elf64_Sym = extern struct {
664 st_shndx: Elf64_Section,734 st_shndx: Elf64_Section,
665 st_value: Elf64_Addr,735 st_value: Elf64_Addr,
666 st_size: Elf64_Xword,736 st_size: Elf64_Xword,
737
738 pub inline fn st_type(self: @This()) u4 {
739 return @truncate(u4, self.st_info);
740 }
741 pub inline fn st_bind(self: @This()) u4 {
742 return @truncate(u4, self.st_info >> 4);
743 }
667};744};
668pub const Elf32_Syminfo = extern struct {745pub const Elf32_Syminfo = extern struct {
669 si_boundto: Elf32_Half,746 si_boundto: Elf32_Half,
...@@ -681,7 +758,7 @@ pub const Elf32_Rel = extern struct {...@@ -681,7 +758,7 @@ pub const Elf32_Rel = extern struct {
681 return @truncate(u24, self.r_info >> 8);758 return @truncate(u24, self.r_info >> 8);
682 }759 }
683 pub inline fn r_type(self: @This()) u8 {760 pub inline fn r_type(self: @This()) u8 {
684 return @truncate(u8, self.r_info & 0xff);761 return @truncate(u8, self.r_info);
685 }762 }
686};763};
687pub const Elf64_Rel = extern struct {764pub const Elf64_Rel = extern struct {
...@@ -692,7 +769,7 @@ pub const Elf64_Rel = extern struct {...@@ -692,7 +769,7 @@ pub const Elf64_Rel = extern struct {
692 return @truncate(u32, self.r_info >> 32);769 return @truncate(u32, self.r_info >> 32);
693 }770 }
694 pub inline fn r_type(self: @This()) u32 {771 pub inline fn r_type(self: @This()) u32 {
695 return @truncate(u32, self.r_info & 0xffffffff);772 return @truncate(u32, self.r_info);
696 }773 }
697};774};
698pub const Elf32_Rela = extern struct {775pub const Elf32_Rela = extern struct {
...@@ -704,7 +781,7 @@ pub const Elf32_Rela = extern struct {...@@ -704,7 +781,7 @@ pub const Elf32_Rela = extern struct {
704 return @truncate(u24, self.r_info >> 8);781 return @truncate(u24, self.r_info >> 8);
705 }782 }
706 pub inline fn r_type(self: @This()) u8 {783 pub inline fn r_type(self: @This()) u8 {
707 return @truncate(u8, self.r_info & 0xff);784 return @truncate(u8, self.r_info);
708 }785 }
709};786};
710pub const Elf64_Rela = extern struct {787pub const Elf64_Rela = extern struct {
...@@ -716,7 +793,7 @@ pub const Elf64_Rela = extern struct {...@@ -716,7 +793,7 @@ pub const Elf64_Rela = extern struct {
716 return @truncate(u32, self.r_info >> 32);793 return @truncate(u32, self.r_info >> 32);
717 }794 }
718 pub inline fn r_type(self: @This()) u32 {795 pub inline fn r_type(self: @This()) u32 {
719 return @truncate(u32, self.r_info & 0xffffffff);796 return @truncate(u32, self.r_info);
720 }797 }
721};798};
722pub const Elf32_Dyn = extern struct {799pub const Elf32_Dyn = extern struct {
...@@ -1630,14 +1707,20 @@ pub const PF_MASKOS = 0x0ff00000;...@@ -1630,14 +1707,20 @@ pub const PF_MASKOS = 0x0ff00000;
1630/// Bits for processor-specific semantics.1707/// Bits for processor-specific semantics.
1631pub const PF_MASKPROC = 0xf0000000;1708pub const PF_MASKPROC = 0xf0000000;
16321709
1633// Special section indexes used in Elf{32,64}_Sym.1710/// Undefined section
1634pub const SHN_UNDEF = 0;1711pub const SHN_UNDEF = 0;
1712/// Start of reserved indices
1635pub const SHN_LORESERVE = 0xff00;1713pub const SHN_LORESERVE = 0xff00;
1714/// Start of processor-specific
1636pub const SHN_LOPROC = 0xff00;1715pub const SHN_LOPROC = 0xff00;
1716/// End of processor-specific
1637pub const SHN_HIPROC = 0xff1f;1717pub const SHN_HIPROC = 0xff1f;
1638pub const SHN_LIVEPATCH = 0xff20;1718pub const SHN_LIVEPATCH = 0xff20;
1719/// Associated symbol is absolute
1639pub const SHN_ABS = 0xfff1;1720pub const SHN_ABS = 0xfff1;
1721/// Associated symbol is common
1640pub const SHN_COMMON = 0xfff2;1722pub const SHN_COMMON = 0xfff2;
1723/// End of reserved indices
1641pub const SHN_HIRESERVE = 0xffff;1724pub const SHN_HIRESERVE = 0xffff;
16421725
1643/// AMD x86-64 relocations.1726/// AMD x86-64 relocations.
lib/std/fmt.zig+2-9
...@@ -41,7 +41,7 @@ pub const FormatOptions = struct {...@@ -41,7 +41,7 @@ pub const FormatOptions = struct {
41/// brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...}41/// brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...}
42/// - *specifier* is a type-dependent formatting option that determines how a type should formatted (see below)42/// - *specifier* is a type-dependent formatting option that determines how a type should formatted (see below)
43/// - *fill* is a single character which is used to pad the formatted text43/// - *fill* is a single character which is used to pad the formatted text
44/// - *alignment* is one of the three characters `<`, `^` or `>`. they define if the text is *left*, *center*, or *right* aligned44/// - *alignment* is one of the three characters `<`, `^`, or `>` to make the text left-, center-, or right-aligned, respectively
45/// - *width* is the total width of the field in characters45/// - *width* is the total width of the field in characters
46/// - *precision* specifies how many decimals a formatted number should have46/// - *precision* specifies how many decimals a formatted number should have
47///47///
...@@ -1428,8 +1428,7 @@ pub fn formatInt(...@@ -1428,8 +1428,7 @@ pub fn formatInt(
1428 var a: MinInt = abs_value;1428 var a: MinInt = abs_value;
1429 var index: usize = buf.len;1429 var index: usize = buf.len;
14301430
1431 // TODO isComptime here because of https://github.com/ziglang/zig/issues/13335.1431 if (base == 10) {
1432 if (base == 10 and !isComptime()) {
1433 while (a >= 100) : (a = @divTrunc(a, 100)) {1432 while (a >= 100) : (a = @divTrunc(a, 100)) {
1434 index -= 2;1433 index -= 2;
1435 buf[index..][0..2].* = digits2(@intCast(usize, a % 100));1434 buf[index..][0..2].* = digits2(@intCast(usize, a % 100));
...@@ -1469,12 +1468,6 @@ pub fn formatInt(...@@ -1469,12 +1468,6 @@ pub fn formatInt(
1469 return formatBuf(buf[index..], options, writer);1468 return formatBuf(buf[index..], options, writer);
1470}1469}
14711470
1472// TODO: Remove once https://github.com/ziglang/zig/issues/868 is resolved.
1473fn isComptime() bool {
1474 var a: u8 = 0;
1475 return @typeInfo(@TypeOf(.{a})).Struct.fields[0].is_comptime;
1476}
1477
1478pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) usize {1471pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) usize {
1479 var fbs = std.io.fixedBufferStream(out_buf);1472 var fbs = std.io.fixedBufferStream(out_buf);
1480 formatInt(value, base, case, options, fbs.writer()) catch unreachable;1473 formatInt(value, base, case, options, fbs.writer()) catch unreachable;
lib/std/fs.zig+13-2
...@@ -1236,6 +1236,7 @@ pub const Dir = struct {...@@ -1236,6 +1236,7 @@ pub const Dir = struct {
1236 .capable_io_mode = std.io.default_mode,1236 .capable_io_mode = std.io.default_mode,
1237 .intended_io_mode = flags.intended_io_mode,1237 .intended_io_mode = flags.intended_io_mode,
1238 };1238 };
1239 errdefer file.close();
1239 var io: w.IO_STATUS_BLOCK = undefined;1240 var io: w.IO_STATUS_BLOCK = undefined;
1240 const range_off: w.LARGE_INTEGER = 0;1241 const range_off: w.LARGE_INTEGER = 0;
1241 const range_len: w.LARGE_INTEGER = 1;1242 const range_len: w.LARGE_INTEGER = 1;
...@@ -1396,6 +1397,7 @@ pub const Dir = struct {...@@ -1396,6 +1397,7 @@ pub const Dir = struct {
1396 .capable_io_mode = std.io.default_mode,1397 .capable_io_mode = std.io.default_mode,
1397 .intended_io_mode = flags.intended_io_mode,1398 .intended_io_mode = flags.intended_io_mode,
1398 };1399 };
1400 errdefer file.close();
1399 var io: w.IO_STATUS_BLOCK = undefined;1401 var io: w.IO_STATUS_BLOCK = undefined;
1400 const range_off: w.LARGE_INTEGER = 0;1402 const range_off: w.LARGE_INTEGER = 0;
1401 const range_len: w.LARGE_INTEGER = 1;1403 const range_len: w.LARGE_INTEGER = 1;
...@@ -2210,7 +2212,7 @@ pub const Dir = struct {...@@ -2210,7 +2212,7 @@ pub const Dir = struct {
2210 var need_to_retry: bool = false;2212 var need_to_retry: bool = false;
2211 parent_dir.deleteDir(name) catch |err| switch (err) {2213 parent_dir.deleteDir(name) catch |err| switch (err) {
2212 error.FileNotFound => {},2214 error.FileNotFound => {},
2213 error.DirNotEmpty => need_to_retry = false,2215 error.DirNotEmpty => need_to_retry = true,
2214 else => |e| return e,2216 else => |e| return e,
2215 };2217 };
22162218
...@@ -2913,6 +2915,7 @@ pub const OpenSelfExeError = error{...@@ -2913,6 +2915,7 @@ pub const OpenSelfExeError = error{
2913 /// On Windows, file paths cannot contain these characters:2915 /// On Windows, file paths cannot contain these characters:
2914 /// '/', '*', '?', '"', '<', '>', '|'2916 /// '/', '*', '?', '"', '<', '>', '|'
2915 BadPathName,2917 BadPathName,
2918 Overflow,
2916 Unexpected,2919 Unexpected,
2917} || os.OpenError || SelfExePathError || os.FlockError;2920} || os.OpenError || SelfExePathError || os.FlockError;
29182921
...@@ -2991,7 +2994,15 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {...@@ -2991,7 +2994,15 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
2991 // TODO could this slice from 0 to out_len instead?2994 // TODO could this slice from 0 to out_len instead?
2992 return mem.sliceTo(out_buffer, 0);2995 return mem.sliceTo(out_buffer, 0);
2993 },2996 },
2994 .openbsd, .haiku => {2997 .haiku => {
2998 // The only possible issue when looking for the self image path is
2999 // when the buffer is too short.
3000 // TODO replace with proper constants
3001 if (os.find_path(null, 1000, null, out_buffer.ptr, out_buffer.len) != 0)
3002 return error.Overflow;
3003 return mem.sliceTo(out_buffer, 0);
3004 },
3005 .openbsd => {
2995 // OpenBSD doesn't support getting the path of a running process, so try to guess it3006 // OpenBSD doesn't support getting the path of a running process, so try to guess it
2996 if (os.argv.len == 0)3007 if (os.argv.len == 0)
2997 return error.FileNotFound;3008 return error.FileNotFound;
lib/std/fs/path.zig+3-4
...@@ -1214,10 +1214,9 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons...@@ -1214,10 +1214,9 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons
1214 try testing.expectEqualStrings(expected_output, result);1214 try testing.expectEqualStrings(expected_output, result);
1215}1215}
12161216
1217/// Returns the extension of the file name (if any).1217/// Searches for a file extension separated by a `.` and returns the string after that `.`.
1218/// This function will search for the file extension (separated by a `.`) and will return the text after the `.`.1218/// Files that end or start with `.` and have no other `.` in their name
1219/// Files that end with `.`, or that start with `.` and have no other `.` in their name,1219/// are considered to have no extension, in which case this returns "".
1220/// are considered to have no extension.
1221/// Examples:1220/// Examples:
1222/// - `"main.zig"` ⇒ `".zig"`1221/// - `"main.zig"` ⇒ `".zig"`
1223/// - `"src/main.zig"` ⇒ `".zig"`1222/// - `"src/main.zig"` ⇒ `".zig"`
lib/std/http.zig+1
...@@ -275,4 +275,5 @@ test {...@@ -275,4 +275,5 @@ test {
275 _ = Client;275 _ = Client;
276 _ = Method;276 _ = Method;
277 _ = Status;277 _ = Status;
278 _ = @import("http/test.zig");
278}279}
lib/std/http/Client.zig+8-9
...@@ -645,7 +645,6 @@ pub const Request = struct {...@@ -645,7 +645,6 @@ pub const Request = struct {
645 if (req.response.parser.state.isContent()) break;645 if (req.response.parser.state.isContent()) break;
646 }646 }
647647
648 req.response.headers = http.Headers{ .allocator = req.client.allocator, .owned = false };
649 try req.response.parse(req.response.parser.header_bytes.items);648 try req.response.parse(req.response.parser.header_bytes.items);
650649
651 if (req.response.status == .switching_protocols) {650 if (req.response.status == .switching_protocols) {
...@@ -765,7 +764,7 @@ pub const Request = struct {...@@ -765,7 +764,7 @@ pub const Request = struct {
765 }764 }
766765
767 if (has_trail) {766 if (has_trail) {
768 req.response.headers = http.Headers{ .allocator = req.client.allocator, .owned = false };767 req.response.headers.clearRetainingCapacity();
769768
770 // The response headers before the trailers are already guaranteed to be valid, so they will always be parsed again and cannot return an error.769 // The response headers before the trailers are already guaranteed to be valid, so they will always be parsed again and cannot return an error.
771 // This will *only* fail for a malformed trailer.770 // This will *only* fail for a malformed trailer.
...@@ -797,18 +796,18 @@ pub const Request = struct {...@@ -797,18 +796,18 @@ pub const Request = struct {
797796
798 /// Write `bytes` to the server. The `transfer_encoding` request header determines how data will be sent.797 /// Write `bytes` to the server. The `transfer_encoding` request header determines how data will be sent.
799 pub fn write(req: *Request, bytes: []const u8) WriteError!usize {798 pub fn write(req: *Request, bytes: []const u8) WriteError!usize {
800 switch (req.headers.transfer_encoding) {799 switch (req.transfer_encoding) {
801 .chunked => {800 .chunked => {
802 try req.connection.data.conn.writer().print("{x}\r\n", .{bytes.len});801 try req.connection.data.buffered.writer().print("{x}\r\n", .{bytes.len});
803 try req.connection.data.conn.writeAll(bytes);802 try req.connection.data.buffered.writeAll(bytes);
804 try req.connection.data.conn.writeAll("\r\n");803 try req.connection.data.buffered.writeAll("\r\n");
805804
806 return bytes.len;805 return bytes.len;
807 },806 },
808 .content_length => |*len| {807 .content_length => |*len| {
809 if (len.* < bytes.len) return error.MessageTooLong;808 if (len.* < bytes.len) return error.MessageTooLong;
810809
811 const amt = try req.connection.data.conn.write(bytes);810 const amt = try req.connection.data.buffered.write(bytes);
812 len.* -= amt;811 len.* -= amt;
813 return amt;812 return amt;
814 },813 },
...@@ -828,7 +827,7 @@ pub const Request = struct {...@@ -828,7 +827,7 @@ pub const Request = struct {
828 /// Finish the body of a request. This notifies the server that you have no more data to send.827 /// Finish the body of a request. This notifies the server that you have no more data to send.
829 pub fn finish(req: *Request) FinishError!void {828 pub fn finish(req: *Request) FinishError!void {
830 switch (req.transfer_encoding) {829 switch (req.transfer_encoding) {
831 .chunked => try req.connection.data.conn.writeAll("0\r\n\r\n"),830 .chunked => try req.connection.data.buffered.writeAll("0\r\n\r\n"),
832 .content_length => |len| if (len != 0) return error.MessageNotCompleted,831 .content_length => |len| if (len != 0) return error.MessageNotCompleted,
833 .none => {},832 .none => {},
834 }833 }
...@@ -1019,7 +1018,7 @@ pub fn request(client: *Client, method: http.Method, uri: Uri, headers: http.Hea...@@ -1019,7 +1018,7 @@ pub fn request(client: *Client, method: http.Method, uri: Uri, headers: http.Hea
1019 .status = undefined,1018 .status = undefined,
1020 .reason = undefined,1019 .reason = undefined,
1021 .version = undefined,1020 .version = undefined,
1022 .headers = undefined,1021 .headers = http.Headers{ .allocator = client.allocator, .owned = false },
1023 .parser = switch (options.header_strategy) {1022 .parser = switch (options.header_strategy) {
1024 .dynamic => |max| proto.HeadersParser.initDynamic(max),1023 .dynamic => |max| proto.HeadersParser.initDynamic(max),
1025 .static => |buf| proto.HeadersParser.initStatic(buf),1024 .static => |buf| proto.HeadersParser.initStatic(buf),
lib/std/http/Headers.zig+73-11
...@@ -68,17 +68,7 @@ pub const Headers = struct {...@@ -68,17 +68,7 @@ pub const Headers = struct {
68 }68 }
6969
70 pub fn deinit(headers: *Headers) void {70 pub fn deinit(headers: *Headers) void {
71 var it = headers.index.iterator();71 headers.deallocateIndexListsAndFields();
72 while (it.next()) |entry| {
73 entry.value_ptr.deinit(headers.allocator);
74
75 if (headers.owned) headers.allocator.free(entry.key_ptr.*);
76 }
77
78 for (headers.list.items) |entry| {
79 if (headers.owned) headers.allocator.free(entry.value);
80 }
81
82 headers.index.deinit(headers.allocator);72 headers.index.deinit(headers.allocator);
83 headers.list.deinit(headers.allocator);73 headers.list.deinit(headers.allocator);
8474
...@@ -255,6 +245,39 @@ pub const Headers = struct {...@@ -255,6 +245,39 @@ pub const Headers = struct {
255245
256 try out_stream.writeAll("\r\n");246 try out_stream.writeAll("\r\n");
257 }247 }
248
249 /// Frees all `HeaderIndexList`s within `index`
250 /// Frees names and values of all fields if they are owned.
251 fn deallocateIndexListsAndFields(headers: *Headers) void {
252 var it = headers.index.iterator();
253 while (it.next()) |entry| {
254 entry.value_ptr.deinit(headers.allocator);
255
256 if (headers.owned) headers.allocator.free(entry.key_ptr.*);
257 }
258
259 if (headers.owned) {
260 for (headers.list.items) |entry| {
261 headers.allocator.free(entry.value);
262 }
263 }
264 }
265
266 /// Clears and frees the underlying data structures.
267 /// Frees names and values if they are owned.
268 pub fn clearAndFree(headers: *Headers) void {
269 headers.deallocateIndexListsAndFields();
270 headers.index.clearAndFree(headers.allocator);
271 headers.list.clearAndFree(headers.allocator);
272 }
273
274 /// Clears the underlying data structures while retaining their capacities.
275 /// Frees names and values if they are owned.
276 pub fn clearRetainingCapacity(headers: *Headers) void {
277 headers.deallocateIndexListsAndFields();
278 headers.index.clearRetainingCapacity();
279 headers.list.clearRetainingCapacity();
280 }
258};281};
259282
260test "Headers.append" {283test "Headers.append" {
...@@ -384,3 +407,42 @@ test "Headers consistency" {...@@ -384,3 +407,42 @@ test "Headers consistency" {
384 try h.formatCommaSeparated("foo", writer);407 try h.formatCommaSeparated("foo", writer);
385 try testing.expectEqualStrings("foo: bar, baz\r\n", fbs.getWritten());408 try testing.expectEqualStrings("foo: bar, baz\r\n", fbs.getWritten());
386}409}
410
411test "Headers.clearRetainingCapacity and clearAndFree" {
412 var h = Headers.init(std.testing.allocator);
413 defer h.deinit();
414
415 h.clearRetainingCapacity();
416
417 try h.append("foo", "bar");
418 try h.append("bar", "world");
419 try h.append("foo", "baz");
420 try h.append("baz", "hello");
421 try testing.expectEqual(@as(usize, 4), h.list.items.len);
422 try testing.expectEqual(@as(usize, 3), h.index.count());
423 const list_capacity = h.list.capacity;
424 const index_capacity = h.index.capacity();
425
426 h.clearRetainingCapacity();
427 try testing.expectEqual(@as(usize, 0), h.list.items.len);
428 try testing.expectEqual(@as(usize, 0), h.index.count());
429 try testing.expectEqual(list_capacity, h.list.capacity);
430 try testing.expectEqual(index_capacity, h.index.capacity());
431
432 try h.append("foo", "bar");
433 try h.append("bar", "world");
434 try h.append("foo", "baz");
435 try h.append("baz", "hello");
436 try testing.expectEqual(@as(usize, 4), h.list.items.len);
437 try testing.expectEqual(@as(usize, 3), h.index.count());
438 // Capacity should still be the same since we shouldn't have needed to grow
439 // when adding back the same fields
440 try testing.expectEqual(list_capacity, h.list.capacity);
441 try testing.expectEqual(index_capacity, h.index.capacity());
442
443 h.clearAndFree();
444 try testing.expectEqual(@as(usize, 0), h.list.items.len);
445 try testing.expectEqual(@as(usize, 0), h.index.count());
446 try testing.expectEqual(@as(usize, 0), h.list.capacity);
447 try testing.expectEqual(@as(usize, 0), h.index.capacity());
448}
lib/std/http/Server.zig+78-2
...@@ -336,8 +336,15 @@ pub const Response = struct {...@@ -336,8 +336,15 @@ pub const Response = struct {
336 headers: http.Headers,336 headers: http.Headers,
337 request: Request,337 request: Request,
338338
339 pub fn deinit(res: *Response) void {
340 res.server.allocator.destroy(res);
341 }
342
339 /// Reset this response to its initial state. This must be called before handling a second request on the same connection.343 /// Reset this response to its initial state. This must be called before handling a second request on the same connection.
340 pub fn reset(res: *Response) void {344 pub fn reset(res: *Response) void {
345 res.request.headers.deinit();
346 res.headers.deinit();
347
341 switch (res.request.compression) {348 switch (res.request.compression) {
342 .none => {},349 .none => {},
343 .deflate => |*deflate| deflate.deinit(),350 .deflate => |*deflate| deflate.deinit(),
...@@ -356,8 +363,6 @@ pub const Response = struct {...@@ -356,8 +363,6 @@ pub const Response = struct {
356 if (res.request.parser.header_bytes_owned) {363 if (res.request.parser.header_bytes_owned) {
357 res.request.parser.header_bytes.deinit(res.server.allocator);364 res.request.parser.header_bytes.deinit(res.server.allocator);
358 }365 }
359
360 res.* = undefined;
361 } else {366 } else {
362 res.request.parser.reset();367 res.request.parser.reset();
363 }368 }
...@@ -656,3 +661,74 @@ pub fn accept(server: *Server, options: HeaderStrategy) AcceptError!*Response {...@@ -656,3 +661,74 @@ pub fn accept(server: *Server, options: HeaderStrategy) AcceptError!*Response {
656661
657 return res;662 return res;
658}663}
664
665test "HTTP server handles a chunked transfer coding request" {
666 const builtin = @import("builtin");
667
668 // This test requires spawning threads.
669 if (builtin.single_threaded) {
670 return error.SkipZigTest;
671 }
672
673 const native_endian = comptime builtin.cpu.arch.endian();
674 if (builtin.zig_backend == .stage2_llvm and native_endian == .Big) {
675 // https://github.com/ziglang/zig/issues/13782
676 return error.SkipZigTest;
677 }
678
679 if (builtin.os.tag == .wasi) return error.SkipZigTest;
680
681 const allocator = std.testing.allocator;
682 const expect = std.testing.expect;
683
684 const max_header_size = 8192;
685 var server = std.http.Server.init(allocator, .{ .reuse_address = true });
686 defer server.deinit();
687
688 const address = try std.net.Address.parseIp("127.0.0.1", 0);
689 try server.listen(address);
690 const server_port = server.socket.listen_address.in.getPort();
691
692 const server_thread = try std.Thread.spawn(.{}, (struct {
693 fn apply(s: *std.http.Server) !void {
694 const res = try s.accept(.{ .dynamic = max_header_size });
695 defer res.deinit();
696 defer res.reset();
697 try res.wait();
698
699 try expect(res.request.transfer_encoding.? == .chunked);
700
701 const server_body: []const u8 = "message from server!\n";
702 res.transfer_encoding = .{ .content_length = server_body.len };
703 try res.headers.append("content-type", "text/plain");
704 try res.headers.append("connection", "close");
705 try res.do();
706
707 var buf: [128]u8 = undefined;
708 const n = try res.readAll(&buf);
709 try expect(std.mem.eql(u8, buf[0..n], "ABCD"));
710 _ = try res.writer().writeAll(server_body);
711 try res.finish();
712 }
713 }).apply, .{&server});
714
715 const request_bytes =
716 "POST / HTTP/1.1\r\n" ++
717 "Content-Type: text/plain\r\n" ++
718 "Transfer-Encoding: chunked\r\n" ++
719 "\r\n" ++
720 "1\r\n" ++
721 "A\r\n" ++
722 "1\r\n" ++
723 "B\r\n" ++
724 "2\r\n" ++
725 "CD\r\n" ++
726 "0\r\n" ++
727 "\r\n";
728
729 const stream = try std.net.tcpConnectToHost(allocator, "127.0.0.1", server_port);
730 defer stream.close();
731 _ = try stream.writeAll(request_bytes[0..]);
732
733 server_thread.join();
734}
lib/std/http/protocol.zig+6-2
...@@ -556,8 +556,12 @@ pub const HeadersParser = struct {...@@ -556,8 +556,12 @@ pub const HeadersParser = struct {
556 switch (r.state) {556 switch (r.state) {
557 .invalid => return error.HttpChunkInvalid,557 .invalid => return error.HttpChunkInvalid,
558 .chunk_data => if (r.next_chunk_length == 0) {558 .chunk_data => if (r.next_chunk_length == 0) {
559 // The trailer section is formatted identically to the header section.559 if (std.mem.eql(u8, bconn.peek(), "\r\n")) {
560 r.state = .seen_rn;560 r.state = .finished;
561 } else {
562 // The trailer section is formatted identically to the header section.
563 r.state = .seen_rn;
564 }
561 r.done = true;565 r.done = true;
562566
563 return out_index;567 return out_index;
lib/std/http/test.zig created+72
...@@ -0,0 +1,72 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4test "client requests server" {
5 const builtin = @import("builtin");
6
7 // This test requires spawning threads.
8 if (builtin.single_threaded) {
9 return error.SkipZigTest;
10 }
11
12 const native_endian = comptime builtin.cpu.arch.endian();
13 if (builtin.zig_backend == .stage2_llvm and native_endian == .Big) {
14 // https://github.com/ziglang/zig/issues/13782
15 return error.SkipZigTest;
16 }
17
18 if (builtin.os.tag == .wasi) return error.SkipZigTest;
19
20 const allocator = std.testing.allocator;
21
22 const max_header_size = 8192;
23 var server = std.http.Server.init(allocator, .{ .reuse_address = true });
24 defer server.deinit();
25
26 const address = try std.net.Address.parseIp("127.0.0.1", 0);
27 try server.listen(address);
28 const server_port = server.socket.listen_address.in.getPort();
29
30 const server_thread = try std.Thread.spawn(.{}, (struct {
31 fn apply(s: *std.http.Server) !void {
32 const res = try s.accept(.{ .dynamic = max_header_size });
33 defer res.deinit();
34 defer res.reset();
35 try res.wait();
36
37 const server_body: []const u8 = "message from server!\n";
38 res.transfer_encoding = .{ .content_length = server_body.len };
39 try res.headers.append("content-type", "text/plain");
40 try res.headers.append("connection", "close");
41 try res.do();
42
43 var buf: [128]u8 = undefined;
44 const n = try res.readAll(&buf);
45 try expect(std.mem.eql(u8, buf[0..n], "Hello, World!\n"));
46 _ = try res.writer().writeAll(server_body);
47 try res.finish();
48 }
49 }).apply, .{&server});
50
51 var uri_buf: [22]u8 = undefined;
52 const uri = try std.Uri.parse(try std.fmt.bufPrint(&uri_buf, "http://127.0.0.1:{d}", .{server_port}));
53 var client = std.http.Client{ .allocator = allocator };
54 defer client.deinit();
55 var client_headers = std.http.Headers{ .allocator = allocator };
56 defer client_headers.deinit();
57 var client_req = try client.request(.POST, uri, client_headers, .{});
58 defer client_req.deinit();
59
60 client_req.transfer_encoding = .{ .content_length = 14 }; // this will be checked to ensure you sent exactly 14 bytes
61 try client_req.start(); // this sends the request
62 try client_req.writeAll("Hello, ");
63 try client_req.writeAll("World!\n");
64 try client_req.finish();
65 try client_req.do(); // this waits for a response
66
67 const body = try client_req.reader().readAllAlloc(allocator, 8192 * 1024);
68 defer allocator.free(body);
69 try expect(std.mem.eql(u8, body, "message from server!\n"));
70
71 server_thread.join();
72}
lib/std/macho.zig+2-2
...@@ -540,13 +540,13 @@ pub const dylib_command = extern struct {...@@ -540,13 +540,13 @@ pub const dylib_command = extern struct {
540 dylib: dylib,540 dylib: dylib,
541};541};
542542
543/// Dynamicaly linked shared libraries are identified by two things. The543/// Dynamically linked shared libraries are identified by two things. The
544/// pathname (the name of the library as found for execution), and the544/// pathname (the name of the library as found for execution), and the
545/// compatibility version number. The pathname must match and the compatibility545/// compatibility version number. The pathname must match and the compatibility
546/// number in the user of the library must be greater than or equal to the546/// number in the user of the library must be greater than or equal to the
547/// library being used. The time stamp is used to record the time a library was547/// library being used. The time stamp is used to record the time a library was
548/// built and copied into user so it can be use to determined if the library used548/// built and copied into user so it can be use to determined if the library used
549/// at runtime is exactly the same as used to built the program.549/// at runtime is exactly the same as used to build the program.
550pub const dylib = extern struct {550pub const dylib = extern struct {
551 /// library's pathname (offset pointing at the end of dylib_command)551 /// library's pathname (offset pointing at the end of dylib_command)
552 name: u32,552 name: u32,
lib/std/math.zig+4-3
...@@ -782,7 +782,8 @@ fn testOverflow() !void {...@@ -782,7 +782,8 @@ fn testOverflow() !void {
782}782}
783783
784/// Returns the absolute value of x, where x is a value of a signed integer type.784/// Returns the absolute value of x, where x is a value of a signed integer type.
785/// See also: `absCast`785/// Does not convert and returns a value of a signed integer type.
786/// Use `absCast` if you want to convert the result and get an unsigned type.
786pub fn absInt(x: anytype) !@TypeOf(x) {787pub fn absInt(x: anytype) !@TypeOf(x) {
787 const T = @TypeOf(x);788 const T = @TypeOf(x);
788 return switch (@typeInfo(T)) {789 return switch (@typeInfo(T)) {
...@@ -1015,8 +1016,8 @@ pub inline fn fabs(value: anytype) @TypeOf(value) {...@@ -1015,8 +1016,8 @@ pub inline fn fabs(value: anytype) @TypeOf(value) {
1015}1016}
10161017
1017/// Returns the absolute value of the integer parameter.1018/// Returns the absolute value of the integer parameter.
1018/// Result is an unsigned integer.1019/// Converts result type to unsigned if needed and returns a value of an unsigned integer type.
1019/// See also: `absInt`1020/// Use `absInt` if you want to keep your integer type signed.
1020pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) {1021pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) {
1021 .ComptimeInt => comptime_int,1022 .ComptimeInt => comptime_int,
1022 .Int => |int_info| std.meta.Int(.unsigned, int_info.bits),1023 .Int => |int_info| std.meta.Int(.unsigned, int_info.bits),
lib/std/mem.zig+1-1
...@@ -227,7 +227,7 @@ pub fn set(comptime T: type, dest: []T, value: T) void {...@@ -227,7 +227,7 @@ pub fn set(comptime T: type, dest: []T, value: T) void {
227/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this227/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this
228/// function used, examine closely - it may be a code smell.228/// function used, examine closely - it may be a code smell.
229/// Zero initializes the type.229/// Zero initializes the type.
230/// This can be used to zero initialize a any type for which it makes sense. Structs will be initialized recursively.230/// This can be used to zero-initialize any type for which it makes sense. Structs will be initialized recursively.
231pub fn zeroes(comptime T: type) T {231pub fn zeroes(comptime T: type) T {
232 switch (@typeInfo(T)) {232 switch (@typeInfo(T)) {
233 .ComptimeInt, .Int, .ComptimeFloat, .Float => {233 .ComptimeInt, .Int, .ComptimeFloat, .Float => {
lib/std/net.zig+13
...@@ -1867,6 +1867,7 @@ pub const StreamServer = struct {...@@ -1867,6 +1867,7 @@ pub const StreamServer = struct {
1867 /// Copied from `Options` on `init`.1867 /// Copied from `Options` on `init`.
1868 kernel_backlog: u31,1868 kernel_backlog: u31,
1869 reuse_address: bool,1869 reuse_address: bool,
1870 reuse_port: bool,
18701871
1871 /// `undefined` until `listen` returns successfully.1872 /// `undefined` until `listen` returns successfully.
1872 listen_address: Address,1873 listen_address: Address,
...@@ -1881,6 +1882,9 @@ pub const StreamServer = struct {...@@ -1881,6 +1882,9 @@ pub const StreamServer = struct {
18811882
1882 /// Enable SO.REUSEADDR on the socket.1883 /// Enable SO.REUSEADDR on the socket.
1883 reuse_address: bool = false,1884 reuse_address: bool = false,
1885
1886 /// Enable SO.REUSEPORT on the socket.
1887 reuse_port: bool = false,
1884 };1888 };
18851889
1886 /// After this call succeeds, resources have been acquired and must1890 /// After this call succeeds, resources have been acquired and must
...@@ -1890,6 +1894,7 @@ pub const StreamServer = struct {...@@ -1890,6 +1894,7 @@ pub const StreamServer = struct {
1890 .sockfd = null,1894 .sockfd = null,
1891 .kernel_backlog = options.kernel_backlog,1895 .kernel_backlog = options.kernel_backlog,
1892 .reuse_address = options.reuse_address,1896 .reuse_address = options.reuse_address,
1897 .reuse_port = options.reuse_port,
1893 .listen_address = undefined,1898 .listen_address = undefined,
1894 };1899 };
1895 }1900 }
...@@ -1920,6 +1925,14 @@ pub const StreamServer = struct {...@@ -1920,6 +1925,14 @@ pub const StreamServer = struct {
1920 &mem.toBytes(@as(c_int, 1)),1925 &mem.toBytes(@as(c_int, 1)),
1921 );1926 );
1922 }1927 }
1928 if (@hasDecl(os.SO, "REUSEPORT") and self.reuse_port) {
1929 try os.setsockopt(
1930 sockfd,
1931 os.SOL.SOCKET,
1932 os.SO.REUSEPORT,
1933 &mem.toBytes(@as(c_int, 1)),
1934 );
1935 }
19231936
1924 var socklen = address.getOsSockLen();1937 var socklen = address.getOsSockLen();
1925 try os.bind(sockfd, &address.any, socklen);1938 try os.bind(sockfd, &address.any, socklen);
lib/std/net/test.zig+21
...@@ -230,6 +230,27 @@ test "listen on ipv4 try connect on ipv6 then ipv4" {...@@ -230,6 +230,27 @@ test "listen on ipv4 try connect on ipv6 then ipv4" {
230 try await client_frame;230 try await client_frame;
231}231}
232232
233test "listen on an in use port" {
234 if (builtin.os.tag != .linux and comptime !builtin.os.tag.isDarwin()) {
235 // TODO build abstractions for other operating systems
236 return error.SkipZigTest;
237 }
238
239 const localhost = try net.Address.parseIp("127.0.0.1", 0);
240
241 var server1 = net.StreamServer.init(net.StreamServer.Options{
242 .reuse_port = true,
243 });
244 defer server1.deinit();
245 try server1.listen(localhost);
246
247 var server2 = net.StreamServer.init(net.StreamServer.Options{
248 .reuse_port = true,
249 });
250 defer server2.deinit();
251 try server2.listen(server1.listen_address);
252}
253
233fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void {254fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void {
234 if (builtin.os.tag == .wasi) return error.SkipZigTest;255 if (builtin.os.tag == .wasi) return error.SkipZigTest;
235256
lib/std/os.zig+4-10
...@@ -4722,11 +4722,8 @@ pub fn sysctl(...@@ -4722,11 +4722,8 @@ pub fn sysctl(
4722 newp: ?*anyopaque,4722 newp: ?*anyopaque,
4723 newlen: usize,4723 newlen: usize,
4724) SysCtlError!void {4724) SysCtlError!void {
4725 if (builtin.os.tag == .wasi) {4725 if (builtin.os.tag == .wasi or builtin.os.tag == .haiku) {
4726 @panic("unsupported"); // TODO should be compile error, not panic4726 @compileError("unsupported OS");
4727 }
4728 if (builtin.os.tag == .haiku) {
4729 @panic("unsupported"); // TODO should be compile error, not panic
4730 }4727 }
47314728
4732 const name_len = math.cast(c_uint, name.len) orelse return error.NameTooLong;4729 const name_len = math.cast(c_uint, name.len) orelse return error.NameTooLong;
...@@ -4747,11 +4744,8 @@ pub fn sysctlbynameZ(...@@ -4747,11 +4744,8 @@ pub fn sysctlbynameZ(
4747 newp: ?*anyopaque,4744 newp: ?*anyopaque,
4748 newlen: usize,4745 newlen: usize,
4749) SysCtlError!void {4746) SysCtlError!void {
4750 if (builtin.os.tag == .wasi) {4747 if (builtin.os.tag == .wasi or builtin.os.tag == .haiku) {
4751 @panic("unsupported"); // TODO should be compile error, not panic4748 @compileError("unsupported OS");
4752 }
4753 if (builtin.os.tag == .haiku) {
4754 @panic("unsupported"); // TODO should be compile error, not panic
4755 }4749 }
47564750
4757 switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {4751 switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {
lib/std/os/linux.zig+4-1
...@@ -3464,7 +3464,10 @@ pub const CAP = struct {...@@ -3464,7 +3464,10 @@ pub const CAP = struct {
3464 pub const WAKE_ALARM = 35;3464 pub const WAKE_ALARM = 35;
3465 pub const BLOCK_SUSPEND = 36;3465 pub const BLOCK_SUSPEND = 36;
3466 pub const AUDIT_READ = 37;3466 pub const AUDIT_READ = 37;
3467 pub const LAST_CAP = AUDIT_READ;3467 pub const PERFMON = 38;
3468 pub const BPF = 39;
3469 pub const CHECKPOINT_RESTORE = 40;
3470 pub const LAST_CAP = CHECKPOINT_RESTORE;
34683471
3469 pub fn valid(x: u8) bool {3472 pub fn valid(x: u8) bool {
3470 return x >= 0 and x <= LAST_CAP;3473 return x >= 0 and x <= LAST_CAP;
lib/std/os/linux/seccomp.zig+1-1
...@@ -20,7 +20,7 @@...@@ -20,7 +20,7 @@
20//!20//!
21//! 1. Each CPU architecture supported by Linux has its own unique ABI and21//! 1. Each CPU architecture supported by Linux has its own unique ABI and
22//! syscall API. It is not guaranteed that the syscall numbers and arguments22//! syscall API. It is not guaranteed that the syscall numbers and arguments
23//! are the same across architectures, or that they're even implemted. Thus,23//! are the same across architectures, or that they're even implemented. Thus,
24//! filters cannot be assumed to be portable without consulting documentation24//! filters cannot be assumed to be portable without consulting documentation
25//! like syscalls(2) and testing on target hardware. This also requires25//! like syscalls(2) and testing on target hardware. This also requires
26//! checking the value of `data.arch` to make sure that a filter was compiled26//! checking the value of `data.arch` to make sure that a filter was compiled
lib/std/os/test.zig+2
...@@ -1101,6 +1101,8 @@ test "isatty" {...@@ -1101,6 +1101,8 @@ test "isatty" {
1101 defer tmp.cleanup();1101 defer tmp.cleanup();
11021102
1103 var file = try tmp.dir.createFile("foo", .{});1103 var file = try tmp.dir.createFile("foo", .{});
1104 defer file.close();
1105
1104 try expectEqual(os.isatty(file.handle), false);1106 try expectEqual(os.isatty(file.handle), false);
1105}1107}
11061108
lib/std/process.zig+10-4
...@@ -818,7 +818,8 @@ pub const ArgIterator = struct {...@@ -818,7 +818,8 @@ pub const ArgIterator = struct {
818 }818 }
819};819};
820820
821/// Use argsWithAllocator() for cross-platform code821/// Holds the command-line arguments, with the program name as the first entry.
822/// Use argsWithAllocator() for cross-platform code.
822pub fn args() ArgIterator {823pub fn args() ArgIterator {
823 return ArgIterator.init();824 return ArgIterator.init();
824}825}
...@@ -1162,12 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {...@@ -1162,12 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {
1162 .linux => {1163 .linux => {
1163 return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;1164 return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
1164 },1165 },
1165 .freebsd => {1166 .freebsd, .netbsd, .openbsd, .dragonfly, .macos => {
1166 var physmem: c_ulong = undefined;1167 var physmem: c_ulong = undefined;
1167 var len: usize = @sizeOf(c_ulong);1168 var len: usize = @sizeOf(c_ulong);
1168 os.sysctlbynameZ("hw.physmem", &physmem, &len, null, 0) catch |err| switch (err) {1169 const name = switch (builtin.os.tag) {
1170 .macos => "hw.memsize",
1171 .netbsd => "hw.physmem64",
1172 else => "hw.physmem",
1173 };
1174 os.sysctlbynameZ(name, &physmem, &len, null, 0) catch |err| switch (err) {
1169 error.NameTooLong, error.UnknownName => unreachable,1175 error.NameTooLong, error.UnknownName => unreachable,
1170 else => |e| return e,1176 else => return error.UnknownTotalSystemMemory,
1171 };1177 };
1172 return @intCast(usize, physmem);1178 return @intCast(usize, physmem);
1173 },1179 },
lib/std/rand.zig+2
...@@ -389,6 +389,8 @@ pub const Random = struct {...@@ -389,6 +389,8 @@ pub const Random = struct {
389389
390 /// Randomly selects an index into `proportions`, where the likelihood of each390 /// Randomly selects an index into `proportions`, where the likelihood of each
391 /// index is weighted by that proportion.391 /// index is weighted by that proportion.
392 /// It is more likely for the index of the last proportion to be returned
393 /// than the index of the first proportion in the slice, and vice versa.
392 ///394 ///
393 /// This is useful for selecting an item from a slice where weights are not equal.395 /// This is useful for selecting an item from a slice where weights are not equal.
394 /// `T` must be a numeric type capable of holding the sum of `proportions`.396 /// `T` must be a numeric type capable of holding the sum of `proportions`.
lib/std/tar.zig+5-2
...@@ -35,7 +35,7 @@ pub const Header = struct {...@@ -35,7 +35,7 @@ pub const Header = struct {
35 pub fn fileSize(header: Header) !u64 {35 pub fn fileSize(header: Header) !u64 {
36 const raw = header.bytes[124..][0..12];36 const raw = header.bytes[124..][0..12];
37 const ltrimmed = std.mem.trimLeft(u8, raw, "0");37 const ltrimmed = std.mem.trimLeft(u8, raw, "0");
38 const rtrimmed = std.mem.trimRight(u8, ltrimmed, "\x00");38 const rtrimmed = std.mem.trimRight(u8, ltrimmed, " \x00");
39 if (rtrimmed.len == 0) return 0;39 if (rtrimmed.len == 0) return 0;
40 return std.fmt.parseInt(u64, rtrimmed, 8);40 return std.fmt.parseInt(u64, rtrimmed, 8);
41 }41 }
...@@ -122,13 +122,16 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi...@@ -122,13 +122,16 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
122 .directory => {122 .directory => {
123 const file_name = try stripComponents(unstripped_file_name, options.strip_components);123 const file_name = try stripComponents(unstripped_file_name, options.strip_components);
124 if (file_name.len != 0) {124 if (file_name.len != 0) {
125 try dir.makeDir(file_name);125 try dir.makePath(file_name);
126 }126 }
127 },127 },
128 .normal => {128 .normal => {
129 if (file_size == 0 and unstripped_file_name.len == 0) return;129 if (file_size == 0 and unstripped_file_name.len == 0) return;
130 const file_name = try stripComponents(unstripped_file_name, options.strip_components);130 const file_name = try stripComponents(unstripped_file_name, options.strip_components);
131131
132 if (std.fs.path.dirname(file_name)) |dir_name| {
133 try dir.makePath(dir_name);
134 }
132 var file = try dir.createFile(file_name, .{});135 var file = try dir.createFile(file_name, .{});
133 defer file.close();136 defer file.close();
134137
src/Air.zig+1-1
...@@ -681,7 +681,7 @@ pub const Inst = struct {...@@ -681,7 +681,7 @@ pub const Inst = struct {
681 /// Uses the `un_op` field.681 /// Uses the `un_op` field.
682 tag_name,682 tag_name,
683683
684 /// Given an error value, return the error name. Result type is always `[:0] const u8`.684 /// Given an error value, return the error name. Result type is always `[:0]const u8`.
685 /// Uses the `un_op` field.685 /// Uses the `un_op` field.
686 error_name,686 error_name,
687687
src/AstGen.zig+75-100
...@@ -839,12 +839,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -839,12 +839,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
839 .slice_open => {839 .slice_open => {
840 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);840 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
841841
842 maybeAdvanceSourceCursorToMainToken(gz, node);842 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
843 const line = gz.astgen.source_line - gz.decl_line;
844 const column = gz.astgen.source_column;
845
846 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);843 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs);
847 try emitDbgStmt(gz, line, column);844 try emitDbgStmt(gz, cursor);
848 const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{845 const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{
849 .lhs = lhs,846 .lhs = lhs,
850 .start = start,847 .start = start,
...@@ -854,14 +851,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -854,14 +851,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
854 .slice => {851 .slice => {
855 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);852 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
856853
857 maybeAdvanceSourceCursorToMainToken(gz, node);854 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
858 const line = gz.astgen.source_line - gz.decl_line;
859 const column = gz.astgen.source_column;
860
861 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice);855 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice);
862 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start);856 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start);
863 const end = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end);857 const end = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end);
864 try emitDbgStmt(gz, line, column);858 try emitDbgStmt(gz, cursor);
865 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{859 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{
866 .lhs = lhs,860 .lhs = lhs,
867 .start = start,861 .start = start,
...@@ -872,15 +866,12 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -872,15 +866,12 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
872 .slice_sentinel => {866 .slice_sentinel => {
873 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);867 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
874868
875 maybeAdvanceSourceCursorToMainToken(gz, node);869 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
876 const line = gz.astgen.source_line - gz.decl_line;
877 const column = gz.astgen.source_column;
878
879 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel);870 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel);
880 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start);871 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start);
881 const end = if (extra.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end) else .none;872 const end = if (extra.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end) else .none;
882 const sentinel = try expr(gz, scope, .{ .rl = .none }, extra.sentinel);873 const sentinel = try expr(gz, scope, .{ .rl = .none }, extra.sentinel);
883 try emitDbgStmt(gz, line, column);874 try emitDbgStmt(gz, cursor);
884 const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{875 const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{
885 .lhs = lhs,876 .lhs = lhs,
886 .start = start,877 .start = start,
...@@ -914,20 +905,16 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -914,20 +905,16 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
914 .ref => {905 .ref => {
915 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);906 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
916907
917 maybeAdvanceSourceCursorToMainToken(gz, node);908 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
918 const line = gz.astgen.source_line - gz.decl_line;909 try emitDbgStmt(gz, cursor);
919 const column = gz.astgen.source_column;
920 try emitDbgStmt(gz, line, column);
921910
922 return gz.addUnNode(.optional_payload_safe_ptr, lhs, node);911 return gz.addUnNode(.optional_payload_safe_ptr, lhs, node);
923 },912 },
924 else => {913 else => {
925 const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);914 const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);
926915
927 maybeAdvanceSourceCursorToMainToken(gz, node);916 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
928 const line = gz.astgen.source_line - gz.decl_line;917 try emitDbgStmt(gz, cursor);
929 const column = gz.astgen.source_column;
930 try emitDbgStmt(gz, line, column);
931918
932 return rvalue(gz, ri, try gz.addUnNode(.optional_payload_safe, lhs, node), node);919 return rvalue(gz, ri, try gz.addUnNode(.optional_payload_safe, lhs, node), node);
933 },920 },
...@@ -3330,23 +3317,17 @@ fn assignOp(...@@ -3330,23 +3317,17 @@ fn assignOp(
33303317
3331 const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs);3318 const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs);
33323319
3333 var line: u32 = undefined;3320 const cursor = switch (op_inst_tag) {
3334 var column: u32 = undefined;3321 .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, infix_node),
3335 switch (op_inst_tag) {3322 else => undefined,
3336 .add, .sub, .mul, .div, .mod_rem => {3323 };
3337 maybeAdvanceSourceCursorToMainToken(gz, infix_node);
3338 line = gz.astgen.source_line - gz.decl_line;
3339 column = gz.astgen.source_column;
3340 },
3341 else => {},
3342 }
3343 const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node);3324 const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node);
3344 const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node);3325 const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node);
3345 const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = lhs_type } }, node_datas[infix_node].rhs);3326 const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = lhs_type } }, node_datas[infix_node].rhs);
33463327
3347 switch (op_inst_tag) {3328 switch (op_inst_tag) {
3348 .add, .sub, .mul, .div, .mod_rem => {3329 .add, .sub, .mul, .div, .mod_rem => {
3349 try emitDbgStmt(gz, line, column);3330 try emitDbgStmt(gz, cursor);
3350 },3331 },
3351 else => {},3332 else => {},
3352 }3333 }
...@@ -5360,8 +5341,7 @@ fn tryExpr(...@@ -5360,8 +5341,7 @@ fn tryExpr(
5360 if (!parent_gz.is_comptime) {5341 if (!parent_gz.is_comptime) {
5361 try emitDbgNode(parent_gz, node);5342 try emitDbgNode(parent_gz, node);
5362 }5343 }
5363 const try_line = astgen.source_line - parent_gz.decl_line;5344 const try_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
5364 const try_column = astgen.source_column;
53655345
5366 const operand_ri: ResultInfo = switch (ri.rl) {5346 const operand_ri: ResultInfo = switch (ri.rl) {
5367 .ref => .{ .rl = .ref, .ctx = .error_handling_expr },5347 .ref => .{ .rl = .ref, .ctx = .error_handling_expr },
...@@ -5382,7 +5362,7 @@ fn tryExpr(...@@ -5382,7 +5362,7 @@ fn tryExpr(
5382 };5362 };
5383 const err_code = try else_scope.addUnNode(err_tag, operand, node);5363 const err_code = try else_scope.addUnNode(err_tag, operand, node);
5384 try genDefers(&else_scope, &fn_block.base, scope, .{ .both = err_code });5364 try genDefers(&else_scope, &fn_block.base, scope, .{ .both = err_code });
5385 try emitDbgStmt(&else_scope, try_line, try_column);5365 try emitDbgStmt(&else_scope, try_lc);
5386 _ = try else_scope.addUnNode(.ret_node, err_code, node);5366 _ = try else_scope.addUnNode(.ret_node, err_code, node);
53875367
5388 try else_scope.setTryBody(try_inst, operand);5368 try else_scope.setTryBody(try_inst, operand);
...@@ -5607,10 +5587,8 @@ fn addFieldAccess(...@@ -5607,10 +5587,8 @@ fn addFieldAccess(
5607 const str_index = try astgen.identAsString(field_ident);5587 const str_index = try astgen.identAsString(field_ident);
5608 const lhs = try expr(gz, scope, lhs_ri, object_node);5588 const lhs = try expr(gz, scope, lhs_ri, object_node);
56095589
5610 maybeAdvanceSourceCursorToMainToken(gz, node);5590 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
5611 const line = gz.astgen.source_line - gz.decl_line;5591 try emitDbgStmt(gz, cursor);
5612 const column = gz.astgen.source_column;
5613 try emitDbgStmt(gz, line, column);
56145592
5615 return gz.addPlNode(tag, node, Zir.Inst.Field{5593 return gz.addPlNode(tag, node, Zir.Inst.Field{
5616 .lhs = lhs,5594 .lhs = lhs,
...@@ -5630,24 +5608,20 @@ fn arrayAccess(...@@ -5630,24 +5608,20 @@ fn arrayAccess(
5630 .ref => {5608 .ref => {
5631 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);5609 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
56325610
5633 maybeAdvanceSourceCursorToMainToken(gz, node);5611 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
5634 const line = gz.astgen.source_line - gz.decl_line;
5635 const column = gz.astgen.source_column;
56365612
5637 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);5613 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);
5638 try emitDbgStmt(gz, line, column);5614 try emitDbgStmt(gz, cursor);
56395615
5640 return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });5616 return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
5641 },5617 },
5642 else => {5618 else => {
5643 const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);5619 const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);
56445620
5645 maybeAdvanceSourceCursorToMainToken(gz, node);5621 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
5646 const line = gz.astgen.source_line - gz.decl_line;
5647 const column = gz.astgen.source_column;
56485622
5649 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);5623 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);
5650 try emitDbgStmt(gz, line, column);5624 try emitDbgStmt(gz, cursor);
56515625
5652 return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node);5626 return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node);
5653 },5627 },
...@@ -5674,21 +5648,15 @@ fn simpleBinOp(...@@ -5674,21 +5648,15 @@ fn simpleBinOp(
5674 }5648 }
56755649
5676 const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node);5650 const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node);
5677 var line: u32 = undefined;5651 const cursor = switch (op_inst_tag) {
5678 var column: u32 = undefined;5652 .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, node),
5679 switch (op_inst_tag) {5653 else => undefined,
5680 .add, .sub, .mul, .div, .mod_rem => {5654 };
5681 maybeAdvanceSourceCursorToMainToken(gz, node);
5682 line = gz.astgen.source_line - gz.decl_line;
5683 column = gz.astgen.source_column;
5684 },
5685 else => {},
5686 }
5687 const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node);5655 const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node);
56885656
5689 switch (op_inst_tag) {5657 switch (op_inst_tag) {
5690 .add, .sub, .mul, .div, .mod_rem => {5658 .add, .sub, .mul, .div, .mod_rem => {
5691 try emitDbgStmt(gz, line, column);5659 try emitDbgStmt(gz, cursor);
5692 },5660 },
5693 else => {},5661 else => {},
5694 }5662 }
...@@ -6787,14 +6755,15 @@ fn switchExpr(...@@ -6787,14 +6755,15 @@ fn switchExpr(
6787 }6755 }
67886756
6789 const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none };6757 const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none };
6758
6790 astgen.advanceSourceCursorToNode(operand_node);6759 astgen.advanceSourceCursorToNode(operand_node);
6791 const operand_line = astgen.source_line - parent_gz.decl_line;6760 const operand_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
6792 const operand_column = astgen.source_column;6761
6793 const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node);6762 const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node);
6794 const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond;6763 const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond;
6795 const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node);6764 const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node);
6796 // Sema expects a dbg_stmt immediately after switch_cond(_ref)6765 // Sema expects a dbg_stmt immediately after switch_cond(_ref)
6797 try emitDbgStmt(parent_gz, operand_line, operand_column);6766 try emitDbgStmt(parent_gz, operand_lc);
6798 // We need the type of the operand to use as the result location for all the prong items.6767 // We need the type of the operand to use as the result location for all the prong items.
6799 const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node);6768 const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node);
6800 const item_ri: ResultInfo = .{ .rl = .{ .ty = cond_ty_inst } };6769 const item_ri: ResultInfo = .{ .rl = .{ .ty = cond_ty_inst } };
...@@ -7154,8 +7123,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7154,8 +7123,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7154 if (!gz.is_comptime) {7123 if (!gz.is_comptime) {
7155 try emitDbgNode(gz, node);7124 try emitDbgNode(gz, node);
7156 }7125 }
7157 const ret_line = astgen.source_line - gz.decl_line;7126 const ret_lc = LineColumn{ astgen.source_line - gz.decl_line, astgen.source_column };
7158 const ret_column = astgen.source_column;
71597127
7160 const defer_outer = &astgen.fn_block.?.base;7128 const defer_outer = &astgen.fn_block.?.base;
71617129
...@@ -7179,13 +7147,13 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7179,13 +7147,13 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7179 const defer_counts = countDefers(defer_outer, scope);7147 const defer_counts = countDefers(defer_outer, scope);
7180 if (!defer_counts.need_err_code) {7148 if (!defer_counts.need_err_code) {
7181 try genDefers(gz, defer_outer, scope, .both_sans_err);7149 try genDefers(gz, defer_outer, scope, .both_sans_err);
7182 try emitDbgStmt(gz, ret_line, ret_column);7150 try emitDbgStmt(gz, ret_lc);
7183 _ = try gz.addStrTok(.ret_err_value, err_name_str_index, ident_token);7151 _ = try gz.addStrTok(.ret_err_value, err_name_str_index, ident_token);
7184 return Zir.Inst.Ref.unreachable_value;7152 return Zir.Inst.Ref.unreachable_value;
7185 }7153 }
7186 const err_code = try gz.addStrTok(.ret_err_value_code, err_name_str_index, ident_token);7154 const err_code = try gz.addStrTok(.ret_err_value_code, err_name_str_index, ident_token);
7187 try genDefers(gz, defer_outer, scope, .{ .both = err_code });7155 try genDefers(gz, defer_outer, scope, .{ .both = err_code });
7188 try emitDbgStmt(gz, ret_line, ret_column);7156 try emitDbgStmt(gz, ret_lc);
7189 _ = try gz.addUnNode(.ret_node, err_code, node);7157 _ = try gz.addUnNode(.ret_node, err_code, node);
7190 return Zir.Inst.Ref.unreachable_value;7158 return Zir.Inst.Ref.unreachable_value;
7191 }7159 }
...@@ -7210,7 +7178,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7210,7 +7178,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7210 // As our last action before the return, "pop" the error trace if needed7178 // As our last action before the return, "pop" the error trace if needed
7211 _ = try gz.addRestoreErrRetIndex(.ret, .always);7179 _ = try gz.addRestoreErrRetIndex(.ret, .always);
72127180
7213 try emitDbgStmt(gz, ret_line, ret_column);7181 try emitDbgStmt(gz, ret_lc);
7214 try gz.addRet(ri, operand, node);7182 try gz.addRet(ri, operand, node);
7215 return Zir.Inst.Ref.unreachable_value;7183 return Zir.Inst.Ref.unreachable_value;
7216 },7184 },
...@@ -7218,7 +7186,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7218,7 +7186,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7218 // Value is always an error. Emit both error defers and regular defers.7186 // Value is always an error. Emit both error defers and regular defers.
7219 const err_code = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand;7187 const err_code = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand;
7220 try genDefers(gz, defer_outer, scope, .{ .both = err_code });7188 try genDefers(gz, defer_outer, scope, .{ .both = err_code });
7221 try emitDbgStmt(gz, ret_line, ret_column);7189 try emitDbgStmt(gz, ret_lc);
7222 try gz.addRet(ri, operand, node);7190 try gz.addRet(ri, operand, node);
7223 return Zir.Inst.Ref.unreachable_value;7191 return Zir.Inst.Ref.unreachable_value;
7224 },7192 },
...@@ -7227,7 +7195,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7227,7 +7195,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7227 if (!defer_counts.have_err) {7195 if (!defer_counts.have_err) {
7228 // Only regular defers; no branch needed.7196 // Only regular defers; no branch needed.
7229 try genDefers(gz, defer_outer, scope, .normal_only);7197 try genDefers(gz, defer_outer, scope, .normal_only);
7230 try emitDbgStmt(gz, ret_line, ret_column);7198 try emitDbgStmt(gz, ret_lc);
72317199
7232 // As our last action before the return, "pop" the error trace if needed7200 // As our last action before the return, "pop" the error trace if needed
7233 const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand;7201 const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand;
...@@ -7250,7 +7218,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7250,7 +7218,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7250 // As our last action before the return, "pop" the error trace if needed7218 // As our last action before the return, "pop" the error trace if needed
7251 _ = try then_scope.addRestoreErrRetIndex(.ret, .always);7219 _ = try then_scope.addRestoreErrRetIndex(.ret, .always);
72527220
7253 try emitDbgStmt(&then_scope, ret_line, ret_column);7221 try emitDbgStmt(&then_scope, ret_lc);
7254 try then_scope.addRet(ri, operand, node);7222 try then_scope.addRet(ri, operand, node);
72557223
7256 var else_scope = gz.makeSubBlock(scope);7224 var else_scope = gz.makeSubBlock(scope);
...@@ -7260,7 +7228,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref...@@ -7260,7 +7228,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
7260 .both = try else_scope.addUnNode(.err_union_code, result, node),7228 .both = try else_scope.addUnNode(.err_union_code, result, node),
7261 };7229 };
7262 try genDefers(&else_scope, defer_outer, scope, which_ones);7230 try genDefers(&else_scope, defer_outer, scope, which_ones);
7263 try emitDbgStmt(&else_scope, ret_line, ret_column);7231 try emitDbgStmt(&else_scope, ret_lc);
7264 try else_scope.addRet(ri, operand, node);7232 try else_scope.addRet(ri, operand, node);
72657233
7266 try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0);7234 try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0);
...@@ -8174,6 +8142,7 @@ fn builtinCall(...@@ -8174,6 +8142,7 @@ fn builtinCall(
8174 .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node),8142 .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node),
8175 .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node),8143 .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node),
8176 .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node),8144 .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node),
8145 .in_comptime => return rvalue(gz, ri, try gz.addNodeExtended(.in_comptime, node), node),
81778146
8178 .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info),8147 .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info),
8179 .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of),8148 .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of),
...@@ -8649,11 +8618,14 @@ fn typeCast(...@@ -8649,11 +8618,14 @@ fn typeCast(
8649 rhs_node: Ast.Node.Index,8618 rhs_node: Ast.Node.Index,
8650 tag: Zir.Inst.Tag,8619 tag: Zir.Inst.Tag,
8651) InnerError!Zir.Inst.Ref {8620) InnerError!Zir.Inst.Ref {
8652 try emitDbgNode(gz, node);8621 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
8622 const result_type = try typeExpr(gz, scope, lhs_node);
8623 const operand = try expr(gz, scope, .{ .rl = .none }, rhs_node);
86538624
8625 try emitDbgStmt(gz, cursor);
8654 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{8626 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
8655 .lhs = try typeExpr(gz, scope, lhs_node),8627 .lhs = result_type,
8656 .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node),8628 .rhs = operand,
8657 });8629 });
8658 return rvalue(gz, ri, result, node);8630 return rvalue(gz, ri, result, node);
8659}8631}
...@@ -8680,14 +8652,15 @@ fn simpleUnOp(...@@ -8680,14 +8652,15 @@ fn simpleUnOp(
8680 operand_node: Ast.Node.Index,8652 operand_node: Ast.Node.Index,
8681 tag: Zir.Inst.Tag,8653 tag: Zir.Inst.Tag,
8682) InnerError!Zir.Inst.Ref {8654) InnerError!Zir.Inst.Ref {
8683 switch (tag) {8655 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
8684 .tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node),
8685 else => {},
8686 }
8687 const operand = if (tag == .compile_error)8656 const operand = if (tag == .compile_error)
8688 try comptimeExpr(gz, scope, operand_ri, operand_node)8657 try comptimeExpr(gz, scope, operand_ri, operand_node)
8689 else8658 else
8690 try expr(gz, scope, operand_ri, operand_node);8659 try expr(gz, scope, operand_ri, operand_node);
8660 switch (tag) {
8661 .tag_name, .error_name, .ptr_to_int => try emitDbgStmt(gz, cursor),
8662 else => {},
8663 }
8691 const result = try gz.addUnNode(tag, operand, node);8664 const result = try gz.addUnNode(tag, operand, node);
8692 return rvalue(gz, ri, result, node);8665 return rvalue(gz, ri, result, node);
8693}8666}
...@@ -8759,12 +8732,12 @@ fn divBuiltin(...@@ -8759,12 +8732,12 @@ fn divBuiltin(
8759 rhs_node: Ast.Node.Index,8732 rhs_node: Ast.Node.Index,
8760 tag: Zir.Inst.Tag,8733 tag: Zir.Inst.Tag,
8761) InnerError!Zir.Inst.Ref {8734) InnerError!Zir.Inst.Ref {
8762 try emitDbgNode(gz, node);8735 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
8736 const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node);
8737 const rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node);
87638738
8764 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{8739 try emitDbgStmt(gz, cursor);
8765 .lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node),8740 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
8766 .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node),
8767 });
8768 return rvalue(gz, ri, result, node);8741 return rvalue(gz, ri, result, node);
8769}8742}
87708743
...@@ -8813,23 +8786,21 @@ fn shiftOp(...@@ -8813,23 +8786,21 @@ fn shiftOp(
8813 rhs_node: Ast.Node.Index,8786 rhs_node: Ast.Node.Index,
8814 tag: Zir.Inst.Tag,8787 tag: Zir.Inst.Tag,
8815) InnerError!Zir.Inst.Ref {8788) InnerError!Zir.Inst.Ref {
8816 var line = gz.astgen.source_line - gz.decl_line;
8817 var column = gz.astgen.source_column;
8818 const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node);8789 const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node);
88198790
8820 switch (gz.astgen.tree.nodes.items(.tag)[node]) {8791 const cursor = switch (gz.astgen.tree.nodes.items(.tag)[node]) {
8821 .shl, .shr => {8792 .shl, .shr => maybeAdvanceSourceCursorToMainToken(gz, node),
8822 maybeAdvanceSourceCursorToMainToken(gz, node);8793 else => undefined,
8823 line = gz.astgen.source_line - gz.decl_line;8794 };
8824 column = gz.astgen.source_column;
8825 },
8826 else => {},
8827 }
88288795
8829 const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node);8796 const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node);
8830 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node);8797 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node);
88318798
8832 try emitDbgStmt(gz, line, column);8799 switch (gz.astgen.tree.nodes.items(.tag)[node]) {
8800 .shl, .shr => try emitDbgStmt(gz, cursor),
8801 else => undefined,
8802 }
8803
8833 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{8804 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
8834 .lhs = lhs,8805 .lhs = lhs,
8835 .rhs = rhs,8806 .rhs = rhs,
...@@ -12593,16 +12564,20 @@ fn detectLocalShadowing(...@@ -12593,16 +12564,20 @@ fn detectLocalShadowing(
12593 };12564 };
12594}12565}
1259512566
12567const LineColumn = struct { u32, u32 };
12568
12596/// Advances the source cursor to the main token of `node` if not in comptime scope.12569/// Advances the source cursor to the main token of `node` if not in comptime scope.
12597/// Usually paired with `emitDbgStmt`.12570/// Usually paired with `emitDbgStmt`.
12598fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void {12571fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineColumn {
12599 if (gz.is_comptime) return;12572 if (gz.is_comptime) return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column };
1260012573
12601 const tree = gz.astgen.tree;12574 const tree = gz.astgen.tree;
12602 const token_starts = tree.tokens.items(.start);12575 const token_starts = tree.tokens.items(.start);
12603 const main_tokens = tree.nodes.items(.main_token);12576 const main_tokens = tree.nodes.items(.main_token);
12604 const node_start = token_starts[main_tokens[node]];12577 const node_start = token_starts[main_tokens[node]];
12605 gz.astgen.advanceSourceCursor(node_start);12578 gz.astgen.advanceSourceCursor(node_start);
12579
12580 return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column };
12606}12581}
1260712582
12608/// Advances the source cursor to the beginning of `node`.12583/// Advances the source cursor to the beginning of `node`.
...@@ -12806,13 +12781,13 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {...@@ -12806,13 +12781,13 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {
12806 return @intCast(u32, count);12781 return @intCast(u32, count);
12807}12782}
1280812783
12809fn emitDbgStmt(gz: *GenZir, line: u32, column: u32) !void {12784fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {
12810 if (gz.is_comptime) return;12785 if (gz.is_comptime) return;
1281112786
12812 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{12787 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
12813 .dbg_stmt = .{12788 .dbg_stmt = .{
12814 .line = line,12789 .line = lc[0],
12815 .column = column,12790 .column = lc[1],
12816 },12791 },
12817 } });12792 } });
12818}12793}
src/Autodoc.zig+2-2
...@@ -4076,7 +4076,7 @@ fn analyzeFancyFunction(...@@ -4076,7 +4076,7 @@ fn analyzeFancyFunction(
4076 else => null,4076 else => null,
4077 };4077 };
40784078
4079 // if we're analyzing a funcion signature (ie without body), we4079 // if we're analyzing a function signature (ie without body), we
4080 // actually don't have an ast_node reserved for us, but since4080 // actually don't have an ast_node reserved for us, but since
4081 // we don't have a name, we don't need it.4081 // we don't have a name, we don't need it.
4082 const src = if (fn_info.body.len == 0) 0 else self_ast_node_index;4082 const src = if (fn_info.body.len == 0) 0 else self_ast_node_index;
...@@ -4229,7 +4229,7 @@ fn analyzeFunction(...@@ -4229,7 +4229,7 @@ fn analyzeFunction(
4229 } else break :blk ret_type_ref;4229 } else break :blk ret_type_ref;
4230 };4230 };
42314231
4232 // if we're analyzing a funcion signature (ie without body), we4232 // if we're analyzing a function signature (ie without body), we
4233 // actually don't have an ast_node reserved for us, but since4233 // actually don't have an ast_node reserved for us, but since
4234 // we don't have a name, we don't need it.4234 // we don't have a name, we don't need it.
4235 const src = if (fn_info.body.len == 0) 0 else self_ast_node_index;4235 const src = if (fn_info.body.len == 0) 0 else self_ast_node_index;
src/BuiltinFn.zig+8
...@@ -58,6 +58,7 @@ pub const Tag = enum {...@@ -58,6 +58,7 @@ pub const Tag = enum {
58 has_decl,58 has_decl,
59 has_field,59 has_field,
60 import,60 import,
61 in_comptime,
61 int_cast,62 int_cast,
62 int_to_enum,63 int_to_enum,
63 int_to_error,64 int_to_error,
...@@ -560,6 +561,13 @@ pub const list = list: {...@@ -560,6 +561,13 @@ pub const list = list: {
560 .param_count = 1,561 .param_count = 1,
561 },562 },
562 },563 },
564 .{
565 "@inComptime",
566 .{
567 .tag = .in_comptime,
568 .param_count = 0,
569 },
570 },
563 .{571 .{
564 "@intCast",572 "@intCast",
565 .{573 .{
src/Module.zig+1-1
...@@ -6626,7 +6626,7 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {...@@ -6626,7 +6626,7 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {
6626 .safety_check_formatted => mod.comp.bin_file.options.use_llvm,6626 .safety_check_formatted => mod.comp.bin_file.options.use_llvm,
6627 .error_return_trace => mod.comp.bin_file.options.use_llvm,6627 .error_return_trace => mod.comp.bin_file.options.use_llvm,
6628 .is_named_enum_value => mod.comp.bin_file.options.use_llvm,6628 .is_named_enum_value => mod.comp.bin_file.options.use_llvm,
6629 .error_set_has_value => mod.comp.bin_file.options.use_llvm,6629 .error_set_has_value => mod.comp.bin_file.options.use_llvm or mod.comp.bin_file.options.target.isWasm(),
6630 .field_reordering => mod.comp.bin_file.options.use_llvm,6630 .field_reordering => mod.comp.bin_file.options.use_llvm,
6631 };6631 };
6632}6632}
src/Sema.zig+44-20
...@@ -1166,6 +1166,7 @@ fn analyzeBodyInner(...@@ -1166,6 +1166,7 @@ fn analyzeBodyInner(
1166 .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode),1166 .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode),
1167 .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode),1167 .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode),
1168 .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode),1168 .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode),
1169 .in_comptime => try sema.zirInComptime( block),
1169 // zig fmt: on1170 // zig fmt: on
11701171
1171 .fence => {1172 .fence => {
...@@ -4155,7 +4156,7 @@ fn validateUnionInit(...@@ -4155,7 +4156,7 @@ fn validateUnionInit(
4155 const msg = try sema.errMsg(4156 const msg = try sema.errMsg(
4156 block,4157 block,
4157 init_src,4158 init_src,
4158 "cannot initialize multiple union fields at once, unions can only have one active field",4159 "cannot initialize multiple union fields at once; unions can only have one active field",
4159 .{},4160 .{},
4160 );4161 );
4161 errdefer msg.destroy(sema.gpa);4162 errdefer msg.destroy(sema.gpa);
...@@ -9646,7 +9647,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9646,7 +9647,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9646 .Union => "union",9647 .Union => "union",
9647 else => unreachable,9648 else => unreachable,
9648 };9649 };
9649 return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', {s} does not have a guaranteed in-memory layout", .{9650 return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{
9650 dest_ty.fmt(sema.mod), container,9651 dest_ty.fmt(sema.mod), container,
9651 });9652 });
9652 },9653 },
...@@ -9709,7 +9710,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -9709,7 +9710,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
9709 .Union => "union",9710 .Union => "union",
9710 else => unreachable,9711 else => unreachable,
9711 };9712 };
9712 return sema.fail(block, operand_src, "cannot @bitCast from '{}', {s} does not have a guaranteed in-memory layout", .{9713 return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{
9713 operand_ty.fmt(sema.mod), container,9714 operand_ty.fmt(sema.mod), container,
9714 });9715 });
9715 },9716 },
...@@ -19626,7 +19627,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19626,7 +19627,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19626 }19627 }
1962719628
19628 try sema.requireRuntimeBlock(block, src, operand_src);19629 try sema.requireRuntimeBlock(block, src, operand_src);
19629 if (block.wantSafety() and try sema.typeHasRuntimeBits(elem_ty)) {19630 if (block.wantSafety() and (try sema.typeHasRuntimeBits(elem_ty) or elem_ty.zigTypeTag() == .Fn)) {
19630 if (!ptr_ty.isAllowzeroPtr()) {19631 if (!ptr_ty.isAllowzeroPtr()) {
19631 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);19632 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
19632 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);19633 try sema.addSafetyCheck(block, is_non_zero, .cast_to_null);
...@@ -19852,7 +19853,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19852,7 +19853,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1985219853
19853 try sema.requireRuntimeBlock(block, src, null);19854 try sema.requireRuntimeBlock(block, src, null);
19854 if (block.wantSafety() and operand_ty.ptrAllowsZero() and !dest_ty.ptrAllowsZero() and19855 if (block.wantSafety() and operand_ty.ptrAllowsZero() and !dest_ty.ptrAllowsZero() and
19855 try sema.typeHasRuntimeBits(dest_ty.elemType2()))19856 (try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))
19856 {19857 {
19857 const ptr_int = try block.addUnOp(.ptrtoint, ptr);19858 const ptr_int = try block.addUnOp(.ptrtoint, ptr);
19858 const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);19859 const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);
...@@ -22466,6 +22467,18 @@ fn zirWorkItem(...@@ -22466,6 +22467,18 @@ fn zirWorkItem(
22466 });22467 });
22467}22468}
2246822469
22470fn zirInComptime(
22471 sema: *Sema,
22472 block: *Block,
22473) CompileError!Air.Inst.Ref {
22474 _ = sema;
22475 if (block.is_comptime) {
22476 return Air.Inst.Ref.bool_true;
22477 } else {
22478 return Air.Inst.Ref.bool_false;
22479 }
22480}
22481
22469fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {22482fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {
22470 if (block.is_comptime) {22483 if (block.is_comptime) {
22471 const msg = msg: {22484 const msg = msg: {
...@@ -23738,7 +23751,6 @@ fn fieldCallBind(...@@ -23738,7 +23751,6 @@ fn fieldCallBind(
23738 {23751 {
23739 const first_param_type = decl_type.fnParamType(0);23752 const first_param_type = decl_type.fnParamType(0);
23740 const first_param_tag = first_param_type.tag();23753 const first_param_tag = first_param_type.tag();
23741 var opt_buf: Type.Payload.ElemType = undefined;
23742 // zig fmt: off23754 // zig fmt: off
23743 if (first_param_tag == .var_args_param or23755 if (first_param_tag == .var_args_param or
23744 first_param_tag == .generic_poison or (23756 first_param_tag == .generic_poison or (
...@@ -23764,17 +23776,29 @@ fn fieldCallBind(...@@ -23764,17 +23776,29 @@ fn fieldCallBind(
23764 .arg0_inst = deref,23776 .arg0_inst = deref,
23765 });23777 });
23766 return sema.addConstant(ty, value);23778 return sema.addConstant(ty, value);
23767 } else if (first_param_tag != .generic_poison and first_param_type.zigTypeTag() == .Optional and23779 } else if (first_param_type.zigTypeTag() == .Optional) {
23768 first_param_type.optionalChild(&opt_buf).eql(concrete_ty, sema.mod))23780 var opt_buf: Type.Payload.ElemType = undefined;
23769 {23781 const child = first_param_type.optionalChild(&opt_buf);
23770 const deref = try sema.analyzeLoad(block, src, object_ptr, src);23782 if (child.eql(concrete_ty, sema.mod)) {
23771 const ty = Type.Tag.bound_fn.init();23783 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
23772 const value = try Value.Tag.bound_fn.create(arena, .{23784 const ty = Type.Tag.bound_fn.init();
23773 .func_inst = decl_val,23785 const value = try Value.Tag.bound_fn.create(arena, .{
23774 .arg0_inst = deref,23786 .func_inst = decl_val,
23775 });23787 .arg0_inst = deref,
23776 return sema.addConstant(ty, value);23788 });
23777 } else if (first_param_tag != .generic_poison and first_param_type.zigTypeTag() == .ErrorUnion and23789 return sema.addConstant(ty, value);
23790 } else if (child.zigTypeTag() == .Pointer and
23791 child.ptrSize() == .One and
23792 child.childType().eql(concrete_ty, sema.mod))
23793 {
23794 const ty = Type.Tag.bound_fn.init();
23795 const value = try Value.Tag.bound_fn.create(arena, .{
23796 .func_inst = decl_val,
23797 .arg0_inst = object_ptr,
23798 });
23799 return sema.addConstant(ty, value);
23800 }
23801 } else if (first_param_type.zigTypeTag() == .ErrorUnion and
23778 first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))23802 first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))
23779 {23803 {
23780 const deref = try sema.analyzeLoad(block, src, object_ptr, src);23804 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
...@@ -26434,7 +26458,7 @@ fn coerceVarArgParam(...@@ -26434,7 +26458,7 @@ fn coerceVarArgParam(
26434 .ComptimeInt, .ComptimeFloat => return sema.fail(26458 .ComptimeInt, .ComptimeFloat => return sema.fail(
26435 block,26459 block,
26436 inst_src,26460 inst_src,
26437 "integer and float literals passed variadic function must be casted to a fixed-size number type",26461 "integer and float literals passed to variadic function must be casted to a fixed-size number type",
26438 .{},26462 .{},
26439 ),26463 ),
26440 .Fn => blk: {26464 .Fn => blk: {
...@@ -27718,7 +27742,7 @@ fn coerceCompatiblePtrs(...@@ -27718,7 +27742,7 @@ fn coerceCompatiblePtrs(
27718 try sema.requireRuntimeBlock(block, inst_src, null);27742 try sema.requireRuntimeBlock(block, inst_src, null);
27719 const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero();27743 const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero();
27720 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and27744 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and
27721 try sema.typeHasRuntimeBits(dest_ty.elemType2()))27745 (try sema.typeHasRuntimeBits(dest_ty.elemType2()) or dest_ty.elemType2().zigTypeTag() == .Fn))
27722 {27746 {
27723 const actual_ptr = if (inst_ty.isSlice())27747 const actual_ptr = if (inst_ty.isSlice())
27724 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)27748 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
...@@ -27891,7 +27915,7 @@ fn coerceAnonStructToUnion(...@@ -27891,7 +27915,7 @@ fn coerceAnonStructToUnion(
27891 const msg = if (field_count > 1) try sema.errMsg(27915 const msg = if (field_count > 1) try sema.errMsg(
27892 block,27916 block,
27893 inst_src,27917 inst_src,
27894 "cannot initialize multiple union fields at once, unions can only have one active field",27918 "cannot initialize multiple union fields at once; unions can only have one active field",
27895 .{},27919 .{},
27896 ) else try sema.errMsg(27920 ) else try sema.errMsg(
27897 block,27921 block,
src/Zir.zig+5-2
...@@ -1994,10 +1994,10 @@ pub const Inst = struct {...@@ -1994,10 +1994,10 @@ pub const Inst = struct {
1994 /// Implement builtin `@cVaArg`.1994 /// Implement builtin `@cVaArg`.
1995 /// `operand` is payload index to `BinNode`.1995 /// `operand` is payload index to `BinNode`.
1996 c_va_arg,1996 c_va_arg,
1997 /// Implement builtin `@cVaStart`.1997 /// Implement builtin `@cVaCopy`.
1998 /// `operand` is payload index to `UnNode`.1998 /// `operand` is payload index to `UnNode`.
1999 c_va_copy,1999 c_va_copy,
2000 /// Implement builtin `@cVaStart`.2000 /// Implement builtin `@cVaEnd`.
2001 /// `operand` is payload index to `UnNode`.2001 /// `operand` is payload index to `UnNode`.
2002 c_va_end,2002 c_va_end,
2003 /// Implement builtin `@cVaStart`.2003 /// Implement builtin `@cVaStart`.
...@@ -2018,6 +2018,9 @@ pub const Inst = struct {...@@ -2018,6 +2018,9 @@ pub const Inst = struct {
2018 /// Implements the `@workGroupId` builtin.2018 /// Implements the `@workGroupId` builtin.
2019 /// `operand` is payload index to `UnNode`.2019 /// `operand` is payload index to `UnNode`.
2020 work_group_id,2020 work_group_id,
2021 /// Implements the `@inComptime` builtin.
2022 /// `operand` is `src_node: i32`.
2023 in_comptime,
20212024
2022 pub const InstData = struct {2025 pub const InstData = struct {
2023 opcode: Extended,2026 opcode: Extended,
src/arch/wasm/CodeGen.zig+90-3
...@@ -1946,6 +1946,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1946,6 +1946,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1946 .ret_addr => func.airRetAddr(inst),1946 .ret_addr => func.airRetAddr(inst),
1947 .tag_name => func.airTagName(inst),1947 .tag_name => func.airTagName(inst),
19481948
1949 .error_set_has_value => func.airErrorSetHasValue(inst),
1950
1949 .mul_sat,1951 .mul_sat,
1950 .mod,1952 .mod,
1951 .assembly,1953 .assembly,
...@@ -1967,7 +1969,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1967,7 +1969,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1967 .set_err_return_trace,1969 .set_err_return_trace,
1968 .save_err_return_trace_index,1970 .save_err_return_trace_index,
1969 .is_named_enum_value,1971 .is_named_enum_value,
1970 .error_set_has_value,
1971 .addrspace_cast,1972 .addrspace_cast,
1972 .vector_store_elem,1973 .vector_store_elem,
1973 .c_va_arg,1974 .c_va_arg,
...@@ -3338,9 +3339,14 @@ fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3338,9 +3339,14 @@ fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3338fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3339fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3339 const un_op = func.air.instructions.items(.data)[inst].un_op;3340 const un_op = func.air.instructions.items(.data)[inst].un_op;
3340 const operand = try func.resolveInst(un_op);3341 const operand = try func.resolveInst(un_op);
3342 const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
3343 const errors_len = WValue{ .memory = sym_index };
33413344
3342 _ = operand;3345 try func.emitWValue(operand);
3343 return func.fail("TODO implement airCmpLtErrorsLen for wasm", .{});3346 const errors_len_val = try func.load(errors_len, Type.err_int, 0);
3347 const result = try func.cmp(.stack, errors_len_val, Type.err_int, .lt);
3348
3349 return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});
3344}3350}
33453351
3346fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3352fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
...@@ -6510,3 +6516,84 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6510,3 +6516,84 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6510 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, func.target);6516 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, func.target);
6511 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);6517 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
6512}6518}
6519
6520fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6521 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
6522
6523 const operand = try func.resolveInst(ty_op.operand);
6524 const error_set_ty = func.air.getRefType(ty_op.ty);
6525 const result = try func.allocLocal(Type.bool);
6526
6527 const names = error_set_ty.errorSetNames();
6528 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);
6529 defer values.deinit();
6530
6531 const module = func.bin_file.base.options.module.?;
6532 var lowest: ?u32 = null;
6533 var highest: ?u32 = null;
6534 for (names) |name| {
6535 const err_int = module.global_error_set.get(name).?;
6536 if (lowest) |*l| {
6537 if (err_int < l.*) {
6538 l.* = err_int;
6539 }
6540 } else {
6541 lowest = err_int;
6542 }
6543 if (highest) |*h| {
6544 if (err_int > h.*) {
6545 highest = err_int;
6546 }
6547 } else {
6548 highest = err_int;
6549 }
6550
6551 values.appendAssumeCapacity(err_int);
6552 }
6553
6554 // start block for 'true' branch
6555 try func.startBlock(.block, wasm.block_empty);
6556 // start block for 'false' branch
6557 try func.startBlock(.block, wasm.block_empty);
6558 // block for the jump table itself
6559 try func.startBlock(.block, wasm.block_empty);
6560
6561 // lower operand to determine jump table target
6562 try func.emitWValue(operand);
6563 try func.addImm32(@intCast(i32, lowest.?));
6564 try func.addTag(.i32_sub);
6565
6566 // Account for default branch so always add '1'
6567 const depth = @intCast(u32, highest.? - lowest.? + 1);
6568 const jump_table: Mir.JumpTable = .{ .length = depth };
6569 const table_extra_index = try func.addExtra(jump_table);
6570 try func.addInst(.{ .tag = .br_table, .data = .{ .payload = table_extra_index } });
6571 try func.mir_extra.ensureUnusedCapacity(func.gpa, depth);
6572
6573 var value: u32 = lowest.?;
6574 while (value <= highest.?) : (value += 1) {
6575 const idx: u32 = blk: {
6576 for (values.items) |val| {
6577 if (val == value) break :blk 1;
6578 }
6579 break :blk 0;
6580 };
6581 func.mir_extra.appendAssumeCapacity(idx);
6582 }
6583 try func.endBlock();
6584
6585 // 'false' branch (i.e. error set does not have value
6586 // ensure we set local to 0 in case the local was re-used.
6587 try func.addImm32(0);
6588 try func.addLabel(.local_set, result.local.value);
6589 try func.addLabel(.br, 1);
6590 try func.endBlock();
6591
6592 // 'true' branch
6593 try func.addImm32(1);
6594 try func.addLabel(.local_set, result.local.value);
6595 try func.addLabel(.br, 0);
6596 try func.endBlock();
6597
6598 return func.finishAir(inst, result, &.{ty_op.operand});
6599}
src/clang.zig+9
...@@ -460,6 +460,9 @@ pub const Expr = opaque {...@@ -460,6 +460,9 @@ pub const Expr = opaque {
460460
461 pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;461 pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
462 extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstantExprKind, *const ASTContext) bool;462 extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstantExprKind, *const ASTContext) bool;
463
464 pub const castToStringLiteral = ZigClangExpr_castToStringLiteral;
465 extern fn ZigClangExpr_castToStringLiteral(*const Expr) ?*const StringLiteral;
463};466};
464467
465pub const FieldDecl = opaque {468pub const FieldDecl = opaque {
...@@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque {...@@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque {
1053 pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;1056 pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;
1054 extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;1057 extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;
10551058
1059 pub const hasArrayFiller = ZigClangInitListExpr_hasArrayFiller;
1060 extern fn ZigClangInitListExpr_hasArrayFiller(*const InitListExpr) bool;
1061
1062 pub const isStringLiteralInit = ZigClangInitListExpr_isStringLiteralInit;
1063 extern fn ZigClangInitListExpr_isStringLiteralInit(*const InitListExpr) bool;
1064
1056 pub const getNumInits = ZigClangInitListExpr_getNumInits;1065 pub const getNumInits = ZigClangInitListExpr_getNumInits;
1057 extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;1066 extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;
10581067
src/link/NvPtx.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1//! NVidia PTX (Paralle Thread Execution)1//! NVidia PTX (Parallel Thread Execution)
2//! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html2//! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html
3//! For this we rely on the nvptx backend of LLVM3//! For this we rely on the nvptx backend of LLVM
4//! Kernel functions need to be marked both as "export" and "callconv(.Kernel)"4//! Kernel functions need to be marked both as "export" and "callconv(.Kernel)"
src/link/Wasm.zig+43
...@@ -1209,6 +1209,11 @@ fn resolveLazySymbols(wasm: *Wasm) !void {...@@ -1209,6 +1209,11 @@ fn resolveLazySymbols(wasm: *Wasm) !void {
1209 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);1209 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
1210 }1210 }
1211 }1211 }
1212 if (wasm.undefs.fetchSwapRemove("__zig_errors_len")) |kv| {
1213 const loc = try wasm.createSyntheticSymbol("__zig_errors_len", .data);
1214 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
1215 _ = wasm.resolved_symbols.swapRemove(kv.value);
1216 }
1212}1217}
12131218
1214// Tries to find a global symbol by its name. Returns null when not found,1219// Tries to find a global symbol by its name. Returns null when not found,
...@@ -2185,6 +2190,43 @@ fn setupInitFunctions(wasm: *Wasm) !void {...@@ -2185,6 +2190,43 @@ fn setupInitFunctions(wasm: *Wasm) !void {
2185 std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);2190 std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);
2186}2191}
21872192
2193/// Generates an atom containing the global error set' size.
2194/// This will only be generated if the symbol exists.
2195fn setupErrorsLen(wasm: *Wasm) !void {
2196 const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return;
2197
2198 const errors_len = wasm.base.options.module.?.global_error_set.count();
2199 // overwrite existing atom if it already exists (maybe the error set has increased)
2200 // if not, allcoate a new atom.
2201 const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {
2202 const atom = wasm.getAtomPtr(index);
2203 if (atom.next) |next_atom_index| {
2204 const next_atom = wasm.getAtomPtr(next_atom_index);
2205 next_atom.prev = atom.prev;
2206 atom.next = null;
2207 }
2208 if (atom.prev) |prev_index| {
2209 const prev_atom = wasm.getAtomPtr(prev_index);
2210 prev_atom.next = atom.next;
2211 atom.prev = null;
2212 }
2213 atom.deinit(wasm);
2214 break :blk index;
2215 } else new_atom: {
2216 const atom_index = @intCast(Atom.Index, wasm.managed_atoms.items.len);
2217 try wasm.symbol_atom.put(wasm.base.allocator, loc, atom_index);
2218 try wasm.managed_atoms.append(wasm.base.allocator, undefined);
2219 break :new_atom atom_index;
2220 };
2221 const atom = wasm.getAtomPtr(atom_index);
2222 atom.* = Atom.empty;
2223 atom.sym_index = loc.index;
2224 atom.size = 2;
2225 try atom.code.writer(wasm.base.allocator).writeIntLittle(u16, @intCast(u16, errors_len));
2226
2227 try wasm.parseAtom(atom_index, .{ .data = .read_only });
2228}
2229
2188/// Creates a function body for the `__wasm_call_ctors` symbol.2230/// Creates a function body for the `__wasm_call_ctors` symbol.
2189/// Loops over all constructors found in `init_funcs` and calls them2231/// Loops over all constructors found in `init_funcs` and calls them
2190/// respectively based on their priority which was sorted by `setupInitFunctions`.2232/// respectively based on their priority which was sorted by `setupInitFunctions`.
...@@ -3317,6 +3359,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -3317,6 +3359,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3317 // So we can rebuild the binary file on each incremental update3359 // So we can rebuild the binary file on each incremental update
3318 defer wasm.resetState();3360 defer wasm.resetState();
3319 try wasm.setupInitFunctions();3361 try wasm.setupInitFunctions();
3362 try wasm.setupErrorsLen();
3320 try wasm.setupStart();3363 try wasm.setupStart();
3321 try wasm.setupImports();3364 try wasm.setupImports();
3322 if (wasm.base.options.module) |mod| {3365 if (wasm.base.options.module) |mod| {
src/main.zig+2-2
...@@ -402,8 +402,8 @@ const usage_build_generic =...@@ -402,8 +402,8 @@ const usage_build_generic =
402 \\ --name [name] Override root name (not a file path)402 \\ --name [name] Override root name (not a file path)
403 \\ -O [mode] Choose what to optimize for403 \\ -O [mode] Choose what to optimize for
404 \\ Debug (default) Optimizations off, safety on404 \\ Debug (default) Optimizations off, safety on
405 \\ ReleaseFast Optimizations on, safety off405 \\ ReleaseFast Optimize for performance, safety off
406 \\ ReleaseSafe Optimizations on, safety on406 \\ ReleaseSafe Optimize for performance, safety on
407 \\ ReleaseSmall Optimize for small binary, safety off407 \\ ReleaseSmall Optimize for small binary, safety off
408 \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name408 \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name
409 \\ deps: [dep],[dep],...409 \\ deps: [dep],[dep],...
src/print_zir.zig+1
...@@ -466,6 +466,7 @@ const Writer = struct {...@@ -466,6 +466,7 @@ const Writer = struct {
466 .frame_address,466 .frame_address,
467 .breakpoint,467 .breakpoint,
468 .c_va_start,468 .c_va_start,
469 .in_comptime,
469 => try self.writeExtNode(stream, extended),470 => try self.writeExtNode(stream, extended),
470471
471 .builtin_src => {472 .builtin_src => {
src/translate_c.zig+27-8
...@@ -2697,6 +2697,13 @@ fn transInitListExprArray(...@@ -2697,6 +2697,13 @@ fn transInitListExprArray(
2697 return Tag.empty_array.create(c.arena, child_type);2697 return Tag.empty_array.create(c.arena, child_type);
2698 }2698 }
26992699
2700 if (expr.isStringLiteralInit()) {
2701 assert(init_count == 1);
2702 const init_expr = expr.getInit(0);
2703 const string_literal = init_expr.castToStringLiteral().?;
2704 return try transStringLiteral(c, scope, string_literal, .used);
2705 }
2706
2700 const init_node = if (init_count != 0) blk: {2707 const init_node = if (init_count != 0) blk: {
2701 const init_list = try c.arena.alloc(Node, init_count);2708 const init_list = try c.arena.alloc(Node, init_count);
27022709
...@@ -2714,6 +2721,7 @@ fn transInitListExprArray(...@@ -2714,6 +2721,7 @@ fn transInitListExprArray(
2714 break :blk init_node;2721 break :blk init_node;
2715 } else null;2722 } else null;
27162723
2724 assert(expr.hasArrayFiller());
2717 const filler_val_expr = expr.getArrayFiller();2725 const filler_val_expr = expr.getArrayFiller();
2718 const filler_node = try Tag.array_filler.create(c.arena, .{2726 const filler_node = try Tag.array_filler.create(c.arena, .{
2719 .type = child_type,2727 .type = child_type,
...@@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {...@@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
4176 try c.global_scope.nodes.append(decl_node);4184 try c.global_scope.nodes.append(decl_node);
4177}4185}
41784186
4187fn transQualTypeInitializedStringLiteral(c: *Context, elem_ty: Node, string_lit: *const clang.StringLiteral) TypeError!Node {
4188 const string_lit_size = string_lit.getLength();
4189 const array_size = @intCast(usize, string_lit_size);
4190
4191 // incomplete array initialized with empty string, will be translated as [1]T{0}
4192 // see https://github.com/ziglang/zig/issues/8256
4193 if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
4194
4195 return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
4196}
4197
4179/// Translate a qualtype for a variable with an initializer. This only matters4198/// Translate a qualtype for a variable with an initializer. This only matters
4180/// for incomplete arrays, since the initializer determines the size of the array.4199/// for incomplete arrays, since the initializer determines the size of the array.
4181fn transQualTypeInitialized(4200fn transQualTypeInitialized(
...@@ -4193,18 +4212,18 @@ fn transQualTypeInitialized(...@@ -4193,18 +4212,18 @@ fn transQualTypeInitialized(
4193 switch (decl_init.getStmtClass()) {4212 switch (decl_init.getStmtClass()) {
4194 .StringLiteralClass => {4213 .StringLiteralClass => {
4195 const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);4214 const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);
4196 const string_lit_size = string_lit.getLength();4215 return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit);
4197 const array_size = @intCast(usize, string_lit_size);
4198
4199 // incomplete array initialized with empty string, will be translated as [1]T{0}
4200 // see https://github.com/ziglang/zig/issues/8256
4201 if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
4202
4203 return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
4204 },4216 },
4205 .InitListExprClass => {4217 .InitListExprClass => {
4206 const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);4218 const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);
4207 const size = init_expr.getNumInits();4219 const size = init_expr.getNumInits();
4220
4221 if (init_expr.isStringLiteralInit()) {
4222 assert(size == 1);
4223 const string_lit = init_expr.getInit(0).castToStringLiteral().?;
4224 return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit);
4225 }
4226
4208 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });4227 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
4209 },4228 },
4210 else => {},4229 else => {},
src/zig_clang.cpp+16
...@@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE...@@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE
2382 return true;2382 return true;
2383}2383}
23842384
2385const ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self) {
2386 auto casted_self = reinterpret_cast<const clang::Expr *>(self);
2387 auto cast = clang::dyn_cast<const clang::StringLiteral>(casted_self);
2388 return reinterpret_cast<const ZigClangStringLiteral *>(cast);
2389}
2390
2385const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {2391const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
2386 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);2392 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2387 const clang::Expr *result = casted->getInit(i);2393 const clang::Expr *result = casted->getInit(i);
...@@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx...@@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx
2394 return reinterpret_cast<const ZigClangExpr *>(result);2400 return reinterpret_cast<const ZigClangExpr *>(result);
2395}2401}
23962402
2403bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *self) {
2404 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2405 return casted->hasArrayFiller();
2406}
2407
2408bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *self) {
2409 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2410 return casted->isStringLiteralInit();
2411}
2412
2397const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {2413const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {
2398 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);2414 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2399 const clang::FieldDecl *result = casted->getInitializedFieldInUnion();2415 const clang::FieldDecl *result = casted->getInitializedFieldInUnion();
src/zig_clang.h+3
...@@ -1220,9 +1220,12 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,...@@ -1220,9 +1220,12 @@ ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsFloat(const struct ZigClangExpr *self,
1220 ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);1220 ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);
1221ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,1221ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
1222 struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);1222 struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);
1223ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self);
12231224
1224ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);1225ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
1225ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);1226ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
1227ZIG_EXTERN_C bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *);
1228ZIG_EXTERN_C bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *);
1226ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);1229ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
1227ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);1230ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);
12281231
stage1/zig.h+619-349
...@@ -253,97 +253,6 @@ typedef char bool;...@@ -253,97 +253,6 @@ typedef char bool;
253#define zig_concat(lhs, rhs) lhs##rhs253#define zig_concat(lhs, rhs) lhs##rhs
254#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)254#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
255255
256#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
257#include <stdatomic.h>
258#define zig_atomic(type) _Atomic(type)
259#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
260#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
261#define zig_atomicrmw_xchg(obj, arg, order, type) atomic_exchange_explicit (obj, arg, order)
262#define zig_atomicrmw_add(obj, arg, order, type) atomic_fetch_add_explicit (obj, arg, order)
263#define zig_atomicrmw_sub(obj, arg, order, type) atomic_fetch_sub_explicit (obj, arg, order)
264#define zig_atomicrmw_or(obj, arg, order, type) atomic_fetch_or_explicit (obj, arg, order)
265#define zig_atomicrmw_xor(obj, arg, order, type) atomic_fetch_xor_explicit (obj, arg, order)
266#define zig_atomicrmw_and(obj, arg, order, type) atomic_fetch_and_explicit (obj, arg, order)
267#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand (obj, arg, order)
268#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
269#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
270#define zig_atomic_store(obj, arg, order, type) atomic_store_explicit (obj, arg, order)
271#define zig_atomic_load(obj, order, type) atomic_load_explicit (obj, order)
272#define zig_fence(order) atomic_thread_fence(order)
273#elif defined(__GNUC__)
274#define memory_order_relaxed __ATOMIC_RELAXED
275#define memory_order_consume __ATOMIC_CONSUME
276#define memory_order_acquire __ATOMIC_ACQUIRE
277#define memory_order_release __ATOMIC_RELEASE
278#define memory_order_acq_rel __ATOMIC_ACQ_REL
279#define memory_order_seq_cst __ATOMIC_SEQ_CST
280#define zig_atomic(type) type
281#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)
282#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)
283#define zig_atomicrmw_xchg(obj, arg, order, type) __atomic_exchange_n(obj, arg, order)
284#define zig_atomicrmw_add(obj, arg, order, type) __atomic_fetch_add (obj, arg, order)
285#define zig_atomicrmw_sub(obj, arg, order, type) __atomic_fetch_sub (obj, arg, order)
286#define zig_atomicrmw_or(obj, arg, order, type) __atomic_fetch_or (obj, arg, order)
287#define zig_atomicrmw_xor(obj, arg, order, type) __atomic_fetch_xor (obj, arg, order)
288#define zig_atomicrmw_and(obj, arg, order, type) __atomic_fetch_and (obj, arg, order)
289#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand(obj, arg, order)
290#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
291#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
292#define zig_atomic_store(obj, arg, order, type) __atomic_store_n (obj, arg, order)
293#define zig_atomic_load(obj, order, type) __atomic_load_n (obj, order)
294#define zig_fence(order) __atomic_thread_fence(order)
295#elif _MSC_VER && (_M_IX86 || _M_X64)
296#define memory_order_relaxed 0
297#define memory_order_consume 1
298#define memory_order_acquire 2
299#define memory_order_release 3
300#define memory_order_acq_rel 4
301#define memory_order_seq_cst 5
302#define zig_atomic(type) type
303#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_expand_concat(zig_msvc_cmpxchg_, type)(obj, &(expected), desired)
304#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_cmpxchg_strong(obj, expected, desired, succ, fail, type)
305#define zig_atomicrmw_xchg(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xchg_, type)(obj, arg)
306#define zig_atomicrmw_add(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_add_, type)(obj, arg)
307#define zig_atomicrmw_sub(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_sub_, type)(obj, arg)
308#define zig_atomicrmw_or(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_or_, type)(obj, arg)
309#define zig_atomicrmw_xor(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xor_, type)(obj, arg)
310#define zig_atomicrmw_and(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_and_, type)(obj, arg)
311#define zig_atomicrmw_nand(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_nand_, type)(obj, arg)
312#define zig_atomicrmw_min(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_min_, type)(obj, arg)
313#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)
314#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)
315#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)
316#if _M_X64
317#define zig_fence(order) __faststorefence()
318#else
319#define zig_fence(order) zig_msvc_atomic_barrier()
320#endif
321
322// TODO: _MSC_VER && (_M_ARM || _M_ARM64)
323#else
324#define memory_order_relaxed 0
325#define memory_order_consume 1
326#define memory_order_acquire 2
327#define memory_order_release 3
328#define memory_order_acq_rel 4
329#define memory_order_seq_cst 5
330#define zig_atomic(type) type
331#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_unimplemented()
332#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_unimplemented()
333#define zig_atomicrmw_xchg(obj, arg, order, type) zig_unimplemented()
334#define zig_atomicrmw_add(obj, arg, order, type) zig_unimplemented()
335#define zig_atomicrmw_sub(obj, arg, order, type) zig_unimplemented()
336#define zig_atomicrmw_or(obj, arg, order, type) zig_unimplemented()
337#define zig_atomicrmw_xor(obj, arg, order, type) zig_unimplemented()
338#define zig_atomicrmw_and(obj, arg, order, type) zig_unimplemented()
339#define zig_atomicrmw_nand(obj, arg, order, type) zig_unimplemented()
340#define zig_atomicrmw_min(obj, arg, order, type) zig_unimplemented()
341#define zig_atomicrmw_max(obj, arg, order, type) zig_unimplemented()
342#define zig_atomic_store(obj, arg, order, type) zig_unimplemented()
343#define zig_atomic_load(obj, order, type) zig_unimplemented()
344#define zig_fence(order) zig_unimplemented()
345#endif
346
347#if __STDC_VERSION__ >= 201112L256#if __STDC_VERSION__ >= 201112L
348#define zig_noreturn _Noreturn257#define zig_noreturn _Noreturn
349#elif zig_has_attribute(noreturn) || defined(zig_gnuc)258#elif zig_has_attribute(noreturn) || defined(zig_gnuc)
...@@ -502,15 +411,6 @@ typedef ptrdiff_t intptr_t;...@@ -502,15 +411,6 @@ typedef ptrdiff_t intptr_t;
502411
503#endif412#endif
504413
505#define zig_make_small_i8(val) INT8_C(val)
506#define zig_make_small_u8(val) UINT8_C(val)
507#define zig_make_small_i16(val) INT16_C(val)
508#define zig_make_small_u16(val) UINT16_C(val)
509#define zig_make_small_i32(val) INT32_C(val)
510#define zig_make_small_u32(val) UINT32_C(val)
511#define zig_make_small_i64(val) INT64_C(val)
512#define zig_make_small_u64(val) UINT64_C(val)
513
514#define zig_minInt_i8 INT8_MIN414#define zig_minInt_i8 INT8_MIN
515#define zig_maxInt_i8 INT8_MAX415#define zig_maxInt_i8 INT8_MAX
516#define zig_minInt_u8 UINT8_C(0)416#define zig_minInt_u8 UINT8_C(0)
...@@ -534,24 +434,24 @@ typedef ptrdiff_t intptr_t;...@@ -534,24 +434,24 @@ typedef ptrdiff_t intptr_t;
534#define zig_minInt_u(w, bits) zig_intLimit(u, w, min, bits)434#define zig_minInt_u(w, bits) zig_intLimit(u, w, min, bits)
535#define zig_maxInt_u(w, bits) zig_intLimit(u, w, max, bits)435#define zig_maxInt_u(w, bits) zig_intLimit(u, w, max, bits)
536436
537#define zig_int_operator(Type, RhsType, operation, operator) \437#define zig_operator(Type, RhsType, operation, operator) \
538 static inline Type zig_##operation(Type lhs, RhsType rhs) { \438 static inline Type zig_##operation(Type lhs, RhsType rhs) { \
539 return lhs operator rhs; \439 return lhs operator rhs; \
540 }440 }
541#define zig_int_basic_operator(Type, operation, operator) \441#define zig_basic_operator(Type, operation, operator) \
542 zig_int_operator(Type, Type, operation, operator)442 zig_operator(Type, Type, operation, operator)
543#define zig_int_shift_operator(Type, operation, operator) \443#define zig_shift_operator(Type, operation, operator) \
544 zig_int_operator(Type, uint8_t, operation, operator)444 zig_operator(Type, uint8_t, operation, operator)
545#define zig_int_helpers(w) \445#define zig_int_helpers(w) \
546 zig_int_basic_operator(uint##w##_t, and_u##w, &) \446 zig_basic_operator(uint##w##_t, and_u##w, &) \
547 zig_int_basic_operator( int##w##_t, and_i##w, &) \447 zig_basic_operator( int##w##_t, and_i##w, &) \
548 zig_int_basic_operator(uint##w##_t, or_u##w, |) \448 zig_basic_operator(uint##w##_t, or_u##w, |) \
549 zig_int_basic_operator( int##w##_t, or_i##w, |) \449 zig_basic_operator( int##w##_t, or_i##w, |) \
550 zig_int_basic_operator(uint##w##_t, xor_u##w, ^) \450 zig_basic_operator(uint##w##_t, xor_u##w, ^) \
551 zig_int_basic_operator( int##w##_t, xor_i##w, ^) \451 zig_basic_operator( int##w##_t, xor_i##w, ^) \
552 zig_int_shift_operator(uint##w##_t, shl_u##w, <<) \452 zig_shift_operator(uint##w##_t, shl_u##w, <<) \
553 zig_int_shift_operator( int##w##_t, shl_i##w, <<) \453 zig_shift_operator( int##w##_t, shl_i##w, <<) \
554 zig_int_shift_operator(uint##w##_t, shr_u##w, >>) \454 zig_shift_operator(uint##w##_t, shr_u##w, >>) \
555\455\
556 static inline int##w##_t zig_shr_i##w(int##w##_t lhs, uint8_t rhs) { \456 static inline int##w##_t zig_shr_i##w(int##w##_t lhs, uint8_t rhs) { \
557 int##w##_t sign_mask = lhs < INT##w##_C(0) ? -INT##w##_C(1) : INT##w##_C(0); \457 int##w##_t sign_mask = lhs < INT##w##_C(0) ? -INT##w##_C(1) : INT##w##_C(0); \
...@@ -576,13 +476,13 @@ typedef ptrdiff_t intptr_t;...@@ -576,13 +476,13 @@ typedef ptrdiff_t intptr_t;
576 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \476 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \
577 } \477 } \
578\478\
579 zig_int_basic_operator(uint##w##_t, div_floor_u##w, /) \479 zig_basic_operator(uint##w##_t, div_floor_u##w, /) \
580\480\
581 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \481 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \
582 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < INT##w##_C(0)); \482 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < INT##w##_C(0)); \
583 } \483 } \
584\484\
585 zig_int_basic_operator(uint##w##_t, mod_u##w, %) \485 zig_basic_operator(uint##w##_t, mod_u##w, %) \
586\486\
587 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \487 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
588 int##w##_t rem = lhs % rhs; \488 int##w##_t rem = lhs % rhs; \
...@@ -1253,8 +1153,8 @@ typedef signed __int128 zig_i128;...@@ -1253,8 +1153,8 @@ typedef signed __int128 zig_i128;
1253#define zig_lo_u128(val) ((uint64_t)((val) >> 0))1153#define zig_lo_u128(val) ((uint64_t)((val) >> 0))
1254#define zig_hi_i128(val) (( int64_t)((val) >> 64))1154#define zig_hi_i128(val) (( int64_t)((val) >> 64))
1255#define zig_lo_i128(val) ((uint64_t)((val) >> 0))1155#define zig_lo_i128(val) ((uint64_t)((val) >> 0))
1256#define zig_bitcast_u128(val) ((zig_u128)(val))1156#define zig_bitCast_u128(val) ((zig_u128)(val))
1257#define zig_bitcast_i128(val) ((zig_i128)(val))1157#define zig_bitCast_i128(val) ((zig_i128)(val))
1258#define zig_cmp_int128(Type) \1158#define zig_cmp_int128(Type) \
1259 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \1159 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1260 return (lhs > rhs) - (lhs < rhs); \1160 return (lhs > rhs) - (lhs < rhs); \
...@@ -1288,8 +1188,8 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;...@@ -1288,8 +1188,8 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
1288#define zig_lo_u128(val) ((val).lo)1188#define zig_lo_u128(val) ((val).lo)
1289#define zig_hi_i128(val) ((val).hi)1189#define zig_hi_i128(val) ((val).hi)
1290#define zig_lo_i128(val) ((val).lo)1190#define zig_lo_i128(val) ((val).lo)
1291#define zig_bitcast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)1191#define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo)
1292#define zig_bitcast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)1192#define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo)
1293#define zig_cmp_int128(Type) \1193#define zig_cmp_int128(Type) \
1294 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \1194 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1295 return (lhs.hi == rhs.hi) \1195 return (lhs.hi == rhs.hi) \
...@@ -1303,9 +1203,6 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;...@@ -1303,9 +1203,6 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
13031203
1304#endif /* zig_has_int128 */1204#endif /* zig_has_int128 */
13051205
1306#define zig_make_small_u128(val) zig_make_u128(0, val)
1307#define zig_make_small_i128(val) zig_make_i128((val) < 0 ? -INT64_C(1) : INT64_C(0), val)
1308
1309#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)1206#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
1310#define zig_maxInt_u128 zig_make_u128(zig_maxInt_u64, zig_maxInt_u64)1207#define zig_maxInt_u128 zig_make_u128(zig_maxInt_u64, zig_maxInt_u64)
1311#define zig_minInt_i128 zig_make_i128(zig_minInt_i64, zig_minInt_u64)1208#define zig_minInt_i128 zig_make_i128(zig_minInt_i64, zig_minInt_u64)
...@@ -1466,18 +1363,18 @@ static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1466,18 +1363,18 @@ static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
1466}1363}
14671364
1468static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {1365static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
1469 return zig_bitcast_u128(zig_mul_i128(zig_bitcast_i128(lhs), zig_bitcast_i128(rhs)));1366 return zig_bitCast_u128(zig_mul_i128(zig_bitCast_i128(lhs), zig_bitCast_i128(rhs)));
1470}1367}
14711368
1472zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);1369zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
1473static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {1370static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
1474 return __udivti3(lhs, rhs);1371 return __udivti3(lhs, rhs);
1475};1372}
14761373
1477zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);1374zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
1478static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {1375static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {
1479 return __divti3(lhs, rhs);1376 return __divti3(lhs, rhs);
1480};1377}
14811378
1482zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);1379zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
1483static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {1380static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
...@@ -1503,10 +1400,6 @@ static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {...@@ -1503,10 +1400,6 @@ static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {
1503#define zig_div_floor_u128 zig_div_trunc_u1281400#define zig_div_floor_u128 zig_div_trunc_u128
1504#define zig_mod_u128 zig_rem_u1281401#define zig_mod_u128 zig_rem_u128
15051402
1506static inline zig_u128 zig_nand_u128(zig_u128 lhs, zig_u128 rhs) {
1507 return zig_not_u128(zig_and_u128(lhs, rhs), 128);
1508}
1509
1510static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) {1403static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) {
1511 return zig_cmp_u128(lhs, rhs) < INT32_C(0) ? lhs : rhs;1404 return zig_cmp_u128(lhs, rhs) < INT32_C(0) ? lhs : rhs;
1512}1405}
...@@ -1538,7 +1431,7 @@ static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {...@@ -1538,7 +1431,7 @@ static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
1538}1431}
15391432
1540static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {1433static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {
1541 return zig_wrap_i128(zig_bitcast_i128(zig_shl_u128(zig_bitcast_u128(lhs), rhs)), bits);1434 return zig_wrap_i128(zig_bitCast_i128(zig_shl_u128(zig_bitCast_u128(lhs), rhs)), bits);
1542}1435}
15431436
1544static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {1437static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
...@@ -1546,7 +1439,7 @@ static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {...@@ -1546,7 +1439,7 @@ static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
1546}1439}
15471440
1548static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {1441static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1549 return zig_wrap_i128(zig_bitcast_i128(zig_add_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);1442 return zig_wrap_i128(zig_bitCast_i128(zig_add_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
1550}1443}
15511444
1552static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {1445static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
...@@ -1554,7 +1447,7 @@ static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {...@@ -1554,7 +1447,7 @@ static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
1554}1447}
15551448
1556static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {1449static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1557 return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);1450 return zig_wrap_i128(zig_bitCast_i128(zig_sub_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
1558}1451}
15591452
1560static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {1453static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
...@@ -1562,7 +1455,7 @@ static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {...@@ -1562,7 +1455,7 @@ static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
1562}1455}
15631456
1564static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {1457static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1565 return zig_wrap_i128(zig_bitcast_i128(zig_mul_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits);1458 return zig_wrap_i128(zig_bitCast_i128(zig_mul_u128(zig_bitCast_u128(lhs), zig_bitCast_u128(rhs))), bits);
1566}1459}
15671460
1568#if zig_has_int1281461#if zig_has_int128
...@@ -1697,7 +1590,7 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8...@@ -1697,7 +1590,7 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8
16971590
1698static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {1591static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
1699 *res = zig_shlw_i128(lhs, rhs, bits);1592 *res = zig_shlw_i128(lhs, rhs, bits);
1700 zig_i128 mask = zig_bitcast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));1593 zig_i128 mask = zig_bitCast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)));
1701 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&1594 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
1702 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);1595 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
1703}1596}
...@@ -1711,7 +1604,7 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {...@@ -1711,7 +1604,7 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
17111604
1712static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {1605static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1713 zig_i128 res;1606 zig_i128 res;
1714 if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res;1607 if (zig_cmp_u128(zig_bitCast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res;
1715 return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);1608 return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
1716}1609}
17171610
...@@ -1755,7 +1648,7 @@ static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {...@@ -1755,7 +1648,7 @@ static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {
1755}1648}
17561649
1757static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) {1650static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) {
1758 return zig_clz_u128(zig_bitcast_u128(val), bits);1651 return zig_clz_u128(zig_bitCast_u128(val), bits);
1759}1652}
17601653
1761static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {1654static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {
...@@ -1764,7 +1657,7 @@ static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {...@@ -1764,7 +1657,7 @@ static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) {
1764}1657}
17651658
1766static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) {1659static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) {
1767 return zig_ctz_u128(zig_bitcast_u128(val), bits);1660 return zig_ctz_u128(zig_bitCast_u128(val), bits);
1768}1661}
17691662
1770static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {1663static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {
...@@ -1773,7 +1666,7 @@ static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {...@@ -1773,7 +1666,7 @@ static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) {
1773}1666}
17741667
1775static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) {1668static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) {
1776 return zig_popcount_u128(zig_bitcast_u128(val), bits);1669 return zig_popcount_u128(zig_bitCast_u128(val), bits);
1777}1670}
17781671
1779static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {1672static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {
...@@ -1788,7 +1681,7 @@ static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {...@@ -1788,7 +1681,7 @@ static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) {
1788}1681}
17891682
1790static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) {1683static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) {
1791 return zig_bitcast_i128(zig_byte_swap_u128(zig_bitcast_u128(val), bits));1684 return zig_bitCast_i128(zig_byte_swap_u128(zig_bitCast_u128(val), bits));
1792}1685}
17931686
1794static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {1687static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {
...@@ -1798,7 +1691,7 @@ static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {...@@ -1798,7 +1691,7 @@ static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) {
1798}1691}
17991692
1800static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {1693static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {
1801 return zig_bitcast_i128(zig_bit_reverse_u128(zig_bitcast_u128(val), bits));1694 return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits));
1802}1695}
18031696
1804/* ========================== Big Integer Support =========================== */1697/* ========================== Big Integer Support =========================== */
...@@ -1972,6 +1865,243 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign...@@ -1972,6 +1865,243 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
1972 return 0;1865 return 0;
1973}1866}
19741867
1868static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1869 uint8_t *res_bytes = res;
1870 const uint8_t *lhs_bytes = lhs;
1871 const uint8_t *rhs_bytes = rhs;
1872 uint16_t byte_offset = 0;
1873 uint16_t remaining_bytes = zig_int_bytes(bits);
1874 (void)is_signed;
1875
1876 while (remaining_bytes >= 128 / CHAR_BIT) {
1877 zig_u128 res_limb;
1878 zig_u128 lhs_limb;
1879 zig_u128 rhs_limb;
1880
1881 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1882 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1883 res_limb = zig_and_u128(lhs_limb, rhs_limb);
1884 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1885
1886 remaining_bytes -= 128 / CHAR_BIT;
1887 byte_offset += 128 / CHAR_BIT;
1888 }
1889
1890 while (remaining_bytes >= 64 / CHAR_BIT) {
1891 uint64_t res_limb;
1892 uint64_t lhs_limb;
1893 uint64_t rhs_limb;
1894
1895 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1896 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1897 res_limb = zig_and_u64(lhs_limb, rhs_limb);
1898 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1899
1900 remaining_bytes -= 64 / CHAR_BIT;
1901 byte_offset += 64 / CHAR_BIT;
1902 }
1903
1904 while (remaining_bytes >= 32 / CHAR_BIT) {
1905 uint32_t res_limb;
1906 uint32_t lhs_limb;
1907 uint32_t rhs_limb;
1908
1909 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1910 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1911 res_limb = zig_and_u32(lhs_limb, rhs_limb);
1912 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1913
1914 remaining_bytes -= 32 / CHAR_BIT;
1915 byte_offset += 32 / CHAR_BIT;
1916 }
1917
1918 while (remaining_bytes >= 16 / CHAR_BIT) {
1919 uint16_t res_limb;
1920 uint16_t lhs_limb;
1921 uint16_t rhs_limb;
1922
1923 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1924 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1925 res_limb = zig_and_u16(lhs_limb, rhs_limb);
1926 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1927
1928 remaining_bytes -= 16 / CHAR_BIT;
1929 byte_offset += 16 / CHAR_BIT;
1930 }
1931
1932 while (remaining_bytes >= 8 / CHAR_BIT) {
1933 uint8_t res_limb;
1934 uint8_t lhs_limb;
1935 uint8_t rhs_limb;
1936
1937 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1938 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1939 res_limb = zig_and_u8(lhs_limb, rhs_limb);
1940 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1941
1942 remaining_bytes -= 8 / CHAR_BIT;
1943 byte_offset += 8 / CHAR_BIT;
1944 }
1945}
1946
1947static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1948 uint8_t *res_bytes = res;
1949 const uint8_t *lhs_bytes = lhs;
1950 const uint8_t *rhs_bytes = rhs;
1951 uint16_t byte_offset = 0;
1952 uint16_t remaining_bytes = zig_int_bytes(bits);
1953 (void)is_signed;
1954
1955 while (remaining_bytes >= 128 / CHAR_BIT) {
1956 zig_u128 res_limb;
1957 zig_u128 lhs_limb;
1958 zig_u128 rhs_limb;
1959
1960 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1961 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1962 res_limb = zig_or_u128(lhs_limb, rhs_limb);
1963 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1964
1965 remaining_bytes -= 128 / CHAR_BIT;
1966 byte_offset += 128 / CHAR_BIT;
1967 }
1968
1969 while (remaining_bytes >= 64 / CHAR_BIT) {
1970 uint64_t res_limb;
1971 uint64_t lhs_limb;
1972 uint64_t rhs_limb;
1973
1974 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1975 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1976 res_limb = zig_or_u64(lhs_limb, rhs_limb);
1977 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1978
1979 remaining_bytes -= 64 / CHAR_BIT;
1980 byte_offset += 64 / CHAR_BIT;
1981 }
1982
1983 while (remaining_bytes >= 32 / CHAR_BIT) {
1984 uint32_t res_limb;
1985 uint32_t lhs_limb;
1986 uint32_t rhs_limb;
1987
1988 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1989 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1990 res_limb = zig_or_u32(lhs_limb, rhs_limb);
1991 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1992
1993 remaining_bytes -= 32 / CHAR_BIT;
1994 byte_offset += 32 / CHAR_BIT;
1995 }
1996
1997 while (remaining_bytes >= 16 / CHAR_BIT) {
1998 uint16_t res_limb;
1999 uint16_t lhs_limb;
2000 uint16_t rhs_limb;
2001
2002 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2003 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2004 res_limb = zig_or_u16(lhs_limb, rhs_limb);
2005 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2006
2007 remaining_bytes -= 16 / CHAR_BIT;
2008 byte_offset += 16 / CHAR_BIT;
2009 }
2010
2011 while (remaining_bytes >= 8 / CHAR_BIT) {
2012 uint8_t res_limb;
2013 uint8_t lhs_limb;
2014 uint8_t rhs_limb;
2015
2016 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2017 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2018 res_limb = zig_or_u8(lhs_limb, rhs_limb);
2019 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2020
2021 remaining_bytes -= 8 / CHAR_BIT;
2022 byte_offset += 8 / CHAR_BIT;
2023 }
2024}
2025
2026static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2027 uint8_t *res_bytes = res;
2028 const uint8_t *lhs_bytes = lhs;
2029 const uint8_t *rhs_bytes = rhs;
2030 uint16_t byte_offset = 0;
2031 uint16_t remaining_bytes = zig_int_bytes(bits);
2032 (void)is_signed;
2033
2034 while (remaining_bytes >= 128 / CHAR_BIT) {
2035 zig_u128 res_limb;
2036 zig_u128 lhs_limb;
2037 zig_u128 rhs_limb;
2038
2039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2040 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2041 res_limb = zig_xor_u128(lhs_limb, rhs_limb);
2042 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2043
2044 remaining_bytes -= 128 / CHAR_BIT;
2045 byte_offset += 128 / CHAR_BIT;
2046 }
2047
2048 while (remaining_bytes >= 64 / CHAR_BIT) {
2049 uint64_t res_limb;
2050 uint64_t lhs_limb;
2051 uint64_t rhs_limb;
2052
2053 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2054 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2055 res_limb = zig_xor_u64(lhs_limb, rhs_limb);
2056 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2057
2058 remaining_bytes -= 64 / CHAR_BIT;
2059 byte_offset += 64 / CHAR_BIT;
2060 }
2061
2062 while (remaining_bytes >= 32 / CHAR_BIT) {
2063 uint32_t res_limb;
2064 uint32_t lhs_limb;
2065 uint32_t rhs_limb;
2066
2067 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2068 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2069 res_limb = zig_xor_u32(lhs_limb, rhs_limb);
2070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2071
2072 remaining_bytes -= 32 / CHAR_BIT;
2073 byte_offset += 32 / CHAR_BIT;
2074 }
2075
2076 while (remaining_bytes >= 16 / CHAR_BIT) {
2077 uint16_t res_limb;
2078 uint16_t lhs_limb;
2079 uint16_t rhs_limb;
2080
2081 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2082 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2083 res_limb = zig_xor_u16(lhs_limb, rhs_limb);
2084 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2085
2086 remaining_bytes -= 16 / CHAR_BIT;
2087 byte_offset += 16 / CHAR_BIT;
2088 }
2089
2090 while (remaining_bytes >= 8 / CHAR_BIT) {
2091 uint8_t res_limb;
2092 uint8_t lhs_limb;
2093 uint8_t rhs_limb;
2094
2095 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2096 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2097 res_limb = zig_xor_u8(lhs_limb, rhs_limb);
2098 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2099
2100 remaining_bytes -= 8 / CHAR_BIT;
2101 byte_offset += 8 / CHAR_BIT;
2102 }
2103}
2104
1975static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {2105static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1976 uint8_t *res_bytes = res;2106 uint8_t *res_bytes = res;
1977 const uint8_t *lhs_bytes = lhs;2107 const uint8_t *lhs_bytes = lhs;
...@@ -2827,24 +2957,20 @@ long double __cdecl nanl(char const* input);...@@ -2827,24 +2957,20 @@ long double __cdecl nanl(char const* input);
2827#endif2957#endif
28282958
2829#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gnuc)2959#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gnuc)
2830#define zig_has_float_builtins 12960#define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16 (__builtin_##name, )(arg)
2831#define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16(__builtin_##name, )(arg)2961#define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32 (__builtin_##name, )(arg)
2832#define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32(__builtin_##name, )(arg)2962#define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64 (__builtin_##name, )(arg)
2833#define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64(__builtin_##name, )(arg)2963#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)
2834#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80(__builtin_##name, )(arg)
2835#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)2964#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
2836#else2965#else
2837#define zig_has_float_builtins 02966#define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr)
2838#define zig_make_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr)2967#define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr)
2839#define zig_make_special_f32(sign, name, arg, repr) zig_float_from_repr_f32(repr)2968#define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr)
2840#define zig_make_special_f64(sign, name, arg, repr) zig_float_from_repr_f64(repr)2969#define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr)
2841#define zig_make_special_f80(sign, name, arg, repr) zig_float_from_repr_f80(repr)2970#define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr)
2842#define zig_make_special_f128(sign, name, arg, repr) zig_float_from_repr_f128(repr)
2843#endif2971#endif
28442972
2845#define zig_has_f16 12973#define zig_has_f16 1
2846#define zig_bitSizeOf_f16 16
2847typedef uint16_t zig_repr_f16;
2848#define zig_libc_name_f16(name) __##name##h2974#define zig_libc_name_f16(name) __##name##h
2849#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)2975#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
2850#if FLT_MANT_DIG == 112976#if FLT_MANT_DIG == 11
...@@ -2854,10 +2980,6 @@ typedef float zig_f16;...@@ -2854,10 +2980,6 @@ typedef float zig_f16;
2854typedef double zig_f16;2980typedef double zig_f16;
2855#define zig_make_f16(fp, repr) fp2981#define zig_make_f16(fp, repr) fp
2856#elif LDBL_MANT_DIG == 112982#elif LDBL_MANT_DIG == 11
2857#define zig_bitSizeOf_c_longdouble 16
2858#ifndef ZIG_TARGET_ABI_MSVC
2859typedef zig_repr_f16 zig_repr_c_longdouble;
2860#endif
2861typedef long double zig_f16;2983typedef long double zig_f16;
2862#define zig_make_f16(fp, repr) fp##l2984#define zig_make_f16(fp, repr) fp##l
2863#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))2985#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))
...@@ -2869,8 +2991,8 @@ typedef __fp16 zig_f16;...@@ -2869,8 +2991,8 @@ typedef __fp16 zig_f16;
2869#else2991#else
2870#undef zig_has_f162992#undef zig_has_f16
2871#define zig_has_f16 02993#define zig_has_f16 0
2872#define zig_bitSizeOf_repr_f16 162994#define zig_repr_f16 u16
2873typedef zig_repr_f16 zig_f16;2995typedef uint16_t zig_f16;
2874#define zig_make_f16(fp, repr) repr2996#define zig_make_f16(fp, repr) repr
2875#undef zig_make_special_f162997#undef zig_make_special_f16
2876#define zig_make_special_f16(sign, name, arg, repr) repr2998#define zig_make_special_f16(sign, name, arg, repr) repr
...@@ -2878,15 +3000,12 @@ typedef zig_repr_f16 zig_f16;...@@ -2878,15 +3000,12 @@ typedef zig_repr_f16 zig_f16;
2878#define zig_init_special_f16(sign, name, arg, repr) repr3000#define zig_init_special_f16(sign, name, arg, repr) repr
2879#endif3001#endif
2880#if __APPLE__ && (defined(__i386__) || defined(__x86_64__))3002#if __APPLE__ && (defined(__i386__) || defined(__x86_64__))
2881typedef zig_repr_f16 zig_compiler_rt_f16;3003typedef uint16_t zig_compiler_rt_f16;
2882#else3004#else
2883typedef zig_f16 zig_compiler_rt_f16;3005typedef zig_f16 zig_compiler_rt_f16;
2884#endif3006#endif
2885#define zig_compiler_rt_abbrev_zig_compiler_rt_f16 zig_compiler_rt_abbrev_zig_f16
28863007
2887#define zig_has_f32 13008#define zig_has_f32 1
2888#define zig_bitSizeOf_f32 32
2889typedef uint32_t zig_repr_f32;
2890#define zig_libc_name_f32(name) name##f3009#define zig_libc_name_f32(name) name##f
2891#if _MSC_VER3010#if _MSC_VER
2892#define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, )3011#define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, )
...@@ -2900,10 +3019,6 @@ typedef float zig_f32;...@@ -2900,10 +3019,6 @@ typedef float zig_f32;
2900typedef double zig_f32;3019typedef double zig_f32;
2901#define zig_make_f32(fp, repr) fp3020#define zig_make_f32(fp, repr) fp
2902#elif LDBL_MANT_DIG == 243021#elif LDBL_MANT_DIG == 24
2903#define zig_bitSizeOf_c_longdouble 32
2904#ifndef ZIG_TARGET_ABI_MSVC
2905typedef zig_repr_f32 zig_repr_c_longdouble;
2906#endif
2907typedef long double zig_f32;3022typedef long double zig_f32;
2908#define zig_make_f32(fp, repr) fp##l3023#define zig_make_f32(fp, repr) fp##l
2909#elif FLT32_MANT_DIG == 243024#elif FLT32_MANT_DIG == 24
...@@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32;...@@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32;
2912#else3027#else
2913#undef zig_has_f323028#undef zig_has_f32
2914#define zig_has_f32 03029#define zig_has_f32 0
2915#define zig_bitSizeOf_repr_f32 323030#define zig_repr_f32 u32
2916typedef zig_repr_f32 zig_f32;3031ypedef uint32_t zig_f32;
2917#define zig_make_f32(fp, repr) repr3032#define zig_make_f32(fp, repr) repr
2918#undef zig_make_special_f323033#undef zig_make_special_f32
2919#define zig_make_special_f32(sign, name, arg, repr) repr3034#define zig_make_special_f32(sign, name, arg, repr) repr
...@@ -2922,20 +3037,12 @@ typedef zig_repr_f32 zig_f32;...@@ -2922,20 +3037,12 @@ typedef zig_repr_f32 zig_f32;
2922#endif3037#endif
29233038
2924#define zig_has_f64 13039#define zig_has_f64 1
2925#define zig_bitSizeOf_f64 64
2926typedef uint64_t zig_repr_f64;
2927#define zig_libc_name_f64(name) name3040#define zig_libc_name_f64(name) name
2928#if _MSC_VER3041#if _MSC_VER
2929#ifdef ZIG_TARGET_ABI_MSVC
2930#define zig_bitSizeOf_c_longdouble 64
2931#ifndef ZIG_TARGET_ABI_MSVC
2932typedef zig_repr_f64 zig_repr_c_longdouble;
2933#endif
2934#endif
2935#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )3042#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
2936#else /* _MSC_VER */3043#else
2937#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)3044#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
2938#endif /* _MSC_VER */3045#endif
2939#if FLT_MANT_DIG == 533046#if FLT_MANT_DIG == 53
2940typedef float zig_f64;3047typedef float zig_f64;
2941#define zig_make_f64(fp, repr) fp##f3048#define zig_make_f64(fp, repr) fp##f
...@@ -2943,10 +3050,6 @@ typedef float zig_f64;...@@ -2943,10 +3050,6 @@ typedef float zig_f64;
2943typedef double zig_f64;3050typedef double zig_f64;
2944#define zig_make_f64(fp, repr) fp3051#define zig_make_f64(fp, repr) fp
2945#elif LDBL_MANT_DIG == 533052#elif LDBL_MANT_DIG == 53
2946#define zig_bitSizeOf_c_longdouble 64
2947#ifndef ZIG_TARGET_ABI_MSVC
2948typedef zig_repr_f64 zig_repr_c_longdouble;
2949#endif
2950typedef long double zig_f64;3053typedef long double zig_f64;
2951#define zig_make_f64(fp, repr) fp##l3054#define zig_make_f64(fp, repr) fp##l
2952#elif FLT64_MANT_DIG == 533055#elif FLT64_MANT_DIG == 53
...@@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64;...@@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64;
2958#else3061#else
2959#undef zig_has_f643062#undef zig_has_f64
2960#define zig_has_f64 03063#define zig_has_f64 0
2961#define zig_bitSizeOf_repr_f64 643064#define zig_repr_f64 u64
2962typedef zig_repr_f64 zig_f64;3065typedef uint64_t zig_f64;
2963#define zig_make_f64(fp, repr) repr3066#define zig_make_f64(fp, repr) repr
2964#undef zig_make_special_f643067#undef zig_make_special_f64
2965#define zig_make_special_f64(sign, name, arg, repr) repr3068#define zig_make_special_f64(sign, name, arg, repr) repr
...@@ -2968,8 +3071,6 @@ typedef zig_repr_f64 zig_f64;...@@ -2968,8 +3071,6 @@ typedef zig_repr_f64 zig_f64;
2968#endif3071#endif
29693072
2970#define zig_has_f80 13073#define zig_has_f80 1
2971#define zig_bitSizeOf_f80 80
2972typedef zig_u128 zig_repr_f80;
2973#define zig_libc_name_f80(name) __##name##x3074#define zig_libc_name_f80(name) __##name##x
2974#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)3075#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
2975#if FLT_MANT_DIG == 643076#if FLT_MANT_DIG == 64
...@@ -2979,10 +3080,6 @@ typedef float zig_f80;...@@ -2979,10 +3080,6 @@ typedef float zig_f80;
2979typedef double zig_f80;3080typedef double zig_f80;
2980#define zig_make_f80(fp, repr) fp3081#define zig_make_f80(fp, repr) fp
2981#elif LDBL_MANT_DIG == 643082#elif LDBL_MANT_DIG == 64
2982#define zig_bitSizeOf_c_longdouble 80
2983#ifndef ZIG_TARGET_ABI_MSVC
2984typedef zig_repr_f80 zig_repr_c_longdouble;
2985#endif
2986typedef long double zig_f80;3083typedef long double zig_f80;
2987#define zig_make_f80(fp, repr) fp##l3084#define zig_make_f80(fp, repr) fp##l
2988#elif FLT80_MANT_DIG == 643085#elif FLT80_MANT_DIG == 64
...@@ -2997,8 +3094,8 @@ typedef __float80 zig_f80;...@@ -2997,8 +3094,8 @@ typedef __float80 zig_f80;
2997#else3094#else
2998#undef zig_has_f803095#undef zig_has_f80
2999#define zig_has_f80 03096#define zig_has_f80 0
3000#define zig_bitSizeOf_repr_f80 1283097#define zig_repr_f80 u128
3001typedef zig_repr_f80 zig_f80;3098typedef zig_u128 zig_f80;
3002#define zig_make_f80(fp, repr) repr3099#define zig_make_f80(fp, repr) repr
3003#undef zig_make_special_f803100#undef zig_make_special_f80
3004#define zig_make_special_f80(sign, name, arg, repr) repr3101#define zig_make_special_f80(sign, name, arg, repr) repr
...@@ -3007,8 +3104,6 @@ typedef zig_repr_f80 zig_f80;...@@ -3007,8 +3104,6 @@ typedef zig_repr_f80 zig_f80;
3007#endif3104#endif
30083105
3009#define zig_has_f128 13106#define zig_has_f128 1
3010#define zig_bitSizeOf_f128 128
3011typedef zig_u128 zig_repr_f128;
3012#define zig_libc_name_f128(name) name##q3107#define zig_libc_name_f128(name) name##q
3013#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)3108#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
3014#if FLT_MANT_DIG == 1133109#if FLT_MANT_DIG == 113
...@@ -3018,10 +3113,6 @@ typedef float zig_f128;...@@ -3018,10 +3113,6 @@ typedef float zig_f128;
3018typedef double zig_f128;3113typedef double zig_f128;
3019#define zig_make_f128(fp, repr) fp3114#define zig_make_f128(fp, repr) fp
3020#elif LDBL_MANT_DIG == 1133115#elif LDBL_MANT_DIG == 113
3021#define zig_bitSizeOf_c_longdouble 128
3022#ifndef ZIG_TARGET_ABI_MSVC
3023typedef zig_repr_f128 zig_repr_c_longdouble;
3024#endif
3025typedef long double zig_f128;3116typedef long double zig_f128;
3026#define zig_make_f128(fp, repr) fp##l3117#define zig_make_f128(fp, repr) fp##l
3027#elif FLT128_MANT_DIG == 1133118#elif FLT128_MANT_DIG == 113
...@@ -3038,50 +3129,49 @@ typedef __float128 zig_f128;...@@ -3038,50 +3129,49 @@ typedef __float128 zig_f128;
3038#else3129#else
3039#undef zig_has_f1283130#undef zig_has_f128
3040#define zig_has_f128 03131#define zig_has_f128 0
3041#define zig_bitSizeOf_repr_f128 128
3042typedef zig_repr_f128 zig_f128;
3043#define zig_make_f128(fp, repr) repr
3044#undef zig_make_special_f1283132#undef zig_make_special_f128
3045#define zig_make_special_f128(sign, name, arg, repr) repr
3046#undef zig_init_special_f1283133#undef zig_init_special_f128
3134#if __APPLE__ || defined(__aarch64__)
3135typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64;
3136zig_basic_operator(zig_v2u64, xor_v2u64, ^)
3137#define zig_repr_f128 v2u64
3138typedef zig_v2u64 zig_f128;
3139#define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi }
3140#define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128
3141#define zig_make_f128(fp, repr) zig_make_f128_##repr
3142#define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3143#define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3144#else
3145#define zig_repr_f128 u128
3146typedef zig_u128 zig_f128;
3147#define zig_make_f128(fp, repr) repr
3148#define zig_make_special_f128(sign, name, arg, repr) repr
3047#define zig_init_special_f128(sign, name, arg, repr) repr3149#define zig_init_special_f128(sign, name, arg, repr) repr
3048#endif3150#endif
3151#endif
30493152
3050#ifdef zig_bitSizeOf_c_longdouble3153#if !_MSC_VER && defined(ZIG_TARGET_ABI_MSVC)
30513154/* Emulate msvc abi on a gnu compiler */
3052#define zig_has_c_longdouble 1
3053#ifdef ZIG_TARGET_ABI_MSVC
3054#undef zig_bitSizeOf_c_longdouble
3055#define zig_bitSizeOf_c_longdouble 64
3056typedef zig_f64 zig_c_longdouble;3155typedef zig_f64 zig_c_longdouble;
3057typedef zig_repr_f64 zig_repr_c_longdouble;3156#elif _MSC_VER && !defined(ZIG_TARGET_ABI_MSVC)
3157/* Emulate gnu abi on an msvc compiler */
3158typedef zig_f128 zig_c_longdouble;
3058#else3159#else
3160/* Target and compiler abi match */
3059typedef long double zig_c_longdouble;3161typedef long double zig_c_longdouble;
3060#endif3162#endif
30613163
3062#else /* zig_bitSizeOf_c_longdouble */3164#define zig_bitCast_float(Type, ReprType) \
30633165 static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \
3064#define zig_has_c_longdouble 0
3065#define zig_bitSizeOf_repr_c_longdouble 128
3066typedef zig_f128 zig_c_longdouble;
3067typedef zig_repr_f128 zig_repr_c_longdouble;
3068
3069#endif /* zig_bitSizeOf_c_longdouble */
3070
3071#if !zig_has_float_builtins
3072#define zig_float_from_repr(Type) \
3073 static inline zig_##Type zig_float_from_repr_##Type(zig_repr_##Type repr) { \
3074 zig_##Type result; \3166 zig_##Type result; \
3075 memcpy(&result, &repr, sizeof(result)); \3167 memcpy(&result, &repr, sizeof(result)); \
3076 return result; \3168 return result; \
3077 }3169 }
30783170zig_bitCast_float(f16, uint16_t)
3079zig_float_from_repr(f16)3171zig_bitCast_float(f32, uint32_t)
3080zig_float_from_repr(f32)3172zig_bitCast_float(f64, uint64_t)
3081zig_float_from_repr(f64)3173zig_bitCast_float(f80, zig_u128)
3082zig_float_from_repr(f80)3174zig_bitCast_float(f128, zig_u128)
3083zig_float_from_repr(f128)
3084#endif
30853175
3086#define zig_cast_f16 (zig_f16)3176#define zig_cast_f16 (zig_f16)
3087#define zig_cast_f32 (zig_f32)3177#define zig_cast_f32 (zig_f32)
...@@ -3095,44 +3185,53 @@ zig_float_from_repr(f128)...@@ -3095,44 +3185,53 @@ zig_float_from_repr(f128)
3095#define zig_cast_f128 (zig_f128)3185#define zig_cast_f128 (zig_f128)
3096#endif3186#endif
30973187
3098#define zig_convert_builtin(ResType, operation, ArgType, version) \3188#define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \
3099 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \3189 zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3100 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType);3190 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \
3101zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f32, 2)3191 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \
3102zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f64, 2)3192 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \
3103zig_convert_builtin(zig_f16, trunc, zig_f80, 2)3193 ResType res; \
3104zig_convert_builtin(zig_f16, trunc, zig_f128, 2)3194 ExternResType extern_res; \
3105zig_convert_builtin(zig_f32, extend, zig_compiler_rt_f16, 2)3195 ExternArgType extern_arg; \
3106zig_convert_builtin(zig_f32, trunc, zig_f64, 2)3196 memcpy(&extern_arg, &arg, sizeof(extern_arg)); \
3107zig_convert_builtin(zig_f32, trunc, zig_f80, 2)3197 extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
3108zig_convert_builtin(zig_f32, trunc, zig_f128, 2)3198 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \
3109zig_convert_builtin(zig_f64, extend, zig_compiler_rt_f16, 2)3199 memcpy(&res, &extern_res, sizeof(res)); \
3110zig_convert_builtin(zig_f64, extend, zig_f32, 2)3200 return extern_res; \
3111zig_convert_builtin(zig_f64, trunc, zig_f80, 2)3201 }
3112zig_convert_builtin(zig_f64, trunc, zig_f128, 2)3202zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2)
3113zig_convert_builtin(zig_f80, extend, zig_f16, 2)3203zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2)
3114zig_convert_builtin(zig_f80, extend, zig_f32, 2)3204zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2)
3115zig_convert_builtin(zig_f80, extend, zig_f64, 2)3205zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2)
3116zig_convert_builtin(zig_f80, trunc, zig_f128, 2)3206zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2)
3117zig_convert_builtin(zig_f128, extend, zig_f16, 2)3207zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2)
3118zig_convert_builtin(zig_f128, extend, zig_f32, 2)3208zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2)
3119zig_convert_builtin(zig_f128, extend, zig_f64, 2)3209zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2)
3120zig_convert_builtin(zig_f128, extend, zig_f80, 2)3210zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2)
31213211zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2)
3122#define zig_float_negate_builtin_0(w) \3212zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2)
3123 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \3213zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2)
3124 return zig_expand_concat(zig_xor_u, zig_bitSizeOf_repr_f##w)( \3214zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2)
3125 arg, \3215zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2)
3126 zig_expand_concat(zig_shl_u, zig_bitSizeOf_repr_f##w)( \3216zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2)
3127 zig_expand_concat(zig_make_small_u, zig_bitSizeOf_repr_f##w)(1), \3217zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2)
3128 UINT8_C(w - 1) \3218zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2)
3129 ) \3219zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2)
3130 ); \3220zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2)
3131 }3221zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2)
3132#define zig_float_negate_builtin_1(w) \3222
3223#define zig_float_negate_builtin_0(w, c, sb) \
3224 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, c sb))
3225#define zig_float_negate_builtin_1(w, c, sb) -arg
3226#define zig_float_negate_builtin(w, c, sb) \
3133 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \3227 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
3134 return -arg; \3228 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, c, sb); \
3135 }3229 }
3230zig_float_negate_builtin(16, , UINT16_C(1) << 15 )
3231zig_float_negate_builtin(32, , UINT32_C(1) << 31 )
3232zig_float_negate_builtin(64, , UINT64_C(1) << 63 )
3233zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0)))
3234zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
31363235
3137#define zig_float_less_builtin_0(Type, operation) \3236#define zig_float_less_builtin_0(Type, operation) \
3138 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \3237 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \
...@@ -3164,19 +3263,18 @@ zig_convert_builtin(zig_f128, extend, zig_f80, 2)...@@ -3164,19 +3263,18 @@ zig_convert_builtin(zig_f128, extend, zig_f80, 2)
3164 }3263 }
31653264
3166#define zig_float_builtins(w) \3265#define zig_float_builtins(w) \
3167 zig_convert_builtin( int32_t, fix, zig_f##w, ) \3266 zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \
3168 zig_convert_builtin(uint32_t, fixuns, zig_f##w, ) \3267 zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \
3169 zig_convert_builtin( int64_t, fix, zig_f##w, ) \3268 zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \
3170 zig_convert_builtin(uint64_t, fixuns, zig_f##w, ) \3269 zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \
3171 zig_convert_builtin(zig_i128, fix, zig_f##w, ) \3270 zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \
3172 zig_convert_builtin(zig_u128, fixuns, zig_f##w, ) \3271 zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \
3173 zig_convert_builtin(zig_f##w, float, int32_t, ) \3272 zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \
3174 zig_convert_builtin(zig_f##w, floatun, uint32_t, ) \3273 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \
3175 zig_convert_builtin(zig_f##w, float, int64_t, ) \3274 zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \
3176 zig_convert_builtin(zig_f##w, floatun, uint64_t, ) \3275 zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) \
3177 zig_convert_builtin(zig_f##w, float, zig_i128, ) \3276 zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \
3178 zig_convert_builtin(zig_f##w, floatun, zig_u128, ) \3277 zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \
3179 zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w) \
3180 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \3278 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
3181 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \3279 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
3182 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \3280 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
...@@ -3224,9 +3322,238 @@ zig_float_builtins(64)...@@ -3224,9 +3322,238 @@ zig_float_builtins(64)
3224zig_float_builtins(80)3322zig_float_builtins(80)
3225zig_float_builtins(128)3323zig_float_builtins(128)
32263324
3325/* ============================ Atomics Support ============================= */
3326
3327/* Note that atomics should be implemented as macros because most
3328 compilers silently discard runtime atomic order information. */
3329
3330/* Define fallback implementations first that can later be undef'd on compilers with builtin support. */
3331/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */
3332#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \
3333 zig_##Type zig_atomicrmw_expected; \
3334 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3335 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3336 res = zig_atomicrmw_expected; \
3337} while (0)
3338#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \
3339 zig_##Type zig_atomicrmw_expected; \
3340 zig_##Type zig_atomicrmw_desired; \
3341 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3342 do { \
3343 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3344 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3345 res = zig_atomicrmw_expected; \
3346} while (0)
3347#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \
3348 zig_##Type zig_atomicrmw_expected; \
3349 zig_##Type zig_atomicrmw_desired; \
3350 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3351 do { \
3352 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3353 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3354 res = zig_atomicrmw_expected; \
3355} while (0)
3356#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \
3357 zig_##Type zig_atomicrmw_expected; \
3358 zig_##Type zig_atomicrmw_desired; \
3359 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3360 do { \
3361 zig_atomicrmw_desired = zig_libc_name_##Type(fmin)(zig_atomicrmw_expected, arg); \
3362 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3363 res = zig_atomicrmw_expected; \
3364} while (0)
3365#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \
3366 zig_##Type zig_atomicrmw_expected; \
3367 zig_##Type zig_atomicrmw_desired; \
3368 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3369 do { \
3370 zig_atomicrmw_desired = zig_libc_name_##Type(fmax)(zig_atomicrmw_expected, arg); \
3371 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3372 res = zig_atomicrmw_expected; \
3373} while (0)
3374
3375#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \
3376 zig_##Type zig_atomicrmw_expected; \
3377 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3378 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3379 res = zig_atomicrmw_expected; \
3380} while (0)
3381#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \
3382 zig_##Type zig_atomicrmw_expected; \
3383 zig_##Type zig_atomicrmw_desired; \
3384 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3385 do { \
3386 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3387 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3388 res = zig_atomicrmw_expected; \
3389} while (0)
3390#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \
3391 zig_##Type zig_atomicrmw_expected; \
3392 zig_##Type zig_atomicrmw_desired; \
3393 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3394 do { \
3395 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3396 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3397 res = zig_atomicrmw_expected; \
3398} while (0)
3399#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \
3400 zig_##Type zig_atomicrmw_expected; \
3401 zig_##Type zig_atomicrmw_desired; \
3402 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3403 do { \
3404 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \
3405 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3406 res = zig_atomicrmw_expected; \
3407} while (0)
3408#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \
3409 zig_##Type zig_atomicrmw_expected; \
3410 zig_##Type zig_atomicrmw_desired; \
3411 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3412 do { \
3413 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \
3414 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3415 res = zig_atomicrmw_expected; \
3416} while (0)
3417#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \
3418 zig_##Type zig_atomicrmw_expected; \
3419 zig_##Type zig_atomicrmw_desired; \
3420 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3421 do { \
3422 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \
3423 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3424 res = zig_atomicrmw_expected; \
3425} while (0)
3426#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \
3427 zig_##Type zig_atomicrmw_expected; \
3428 zig_##Type zig_atomicrmw_desired; \
3429 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3430 do { \
3431 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \
3432 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3433 res = zig_atomicrmw_expected; \
3434} while (0)
3435#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \
3436 zig_##Type zig_atomicrmw_expected; \
3437 zig_##Type zig_atomicrmw_desired; \
3438 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3439 do { \
3440 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \
3441 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3442 res = zig_atomicrmw_expected; \
3443} while (0)
3444#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \
3445 zig_##Type zig_atomicrmw_expected; \
3446 zig_##Type zig_atomicrmw_desired; \
3447 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3448 do { \
3449 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \
3450 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3451 res = zig_atomicrmw_expected; \
3452} while (0)
3453
3454#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
3455#include <stdatomic.h>
3456typedef enum memory_order zig_memory_order;
3457#define zig_atomic(Type) _Atomic(Type)
3458#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
3459#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
3460#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = atomic_exchange_explicit (obj, arg, order)
3461#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = atomic_fetch_add_explicit (obj, arg, order)
3462#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = atomic_fetch_sub_explicit (obj, arg, order)
3463#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = atomic_fetch_or_explicit (obj, arg, order)
3464#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = atomic_fetch_xor_explicit (obj, arg, order)
3465#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = atomic_fetch_and_explicit (obj, arg, order)
3466#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
3467#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
3468#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
3469#define zig_atomic_store( obj, arg, order, Type, ReprType) atomic_store_explicit (obj, arg, order)
3470#define zig_atomic_load(res, obj, order, Type, ReprType) res = atomic_load_explicit (obj, order)
3471#undef zig_atomicrmw_xchg_float
3472#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3473#undef zig_atomicrmw_add_float
3474#define zig_atomicrmw_add_float zig_atomicrmw_add
3475#undef zig_atomicrmw_sub_float
3476#define zig_atomicrmw_sub_float zig_atomicrmw_sub
3477#define zig_fence(order) atomic_thread_fence(order)
3478#elif defined(__GNUC__)
3479typedef int zig_memory_order;
3480#define memory_order_relaxed __ATOMIC_RELAXED
3481#define memory_order_consume __ATOMIC_CONSUME
3482#define memory_order_acquire __ATOMIC_ACQUIRE
3483#define memory_order_release __ATOMIC_RELEASE
3484#define memory_order_acq_rel __ATOMIC_ACQ_REL
3485#define memory_order_seq_cst __ATOMIC_SEQ_CST
3486#define zig_atomic(Type) Type
3487#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)
3488#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), true, succ, fail)
3489#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, &(arg), &(res), order)
3490#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_add (obj, arg, order)
3491#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_sub (obj, arg, order)
3492#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_or (obj, arg, order)
3493#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_xor (obj, arg, order)
3494#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_and (obj, arg, order)
3495#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
3496#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
3497#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
3498#define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, &(arg), order)
3499#define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order)
3500#undef zig_atomicrmw_xchg_float
3501#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3502#define zig_fence(order) __atomic_thread_fence(order)
3503#elif _MSC_VER && (_M_IX86 || _M_X64)
3504#define memory_order_relaxed 0
3505#define memory_order_consume 1
3506#define memory_order_acquire 2
3507#define memory_order_release 3
3508#define memory_order_acq_rel 4
3509#define memory_order_seq_cst 5
3510#define zig_atomic(Type) Type
3511#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)
3512#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType)
3513#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xchg_##Type(obj, arg)
3514#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_add_ ##Type(obj, arg)
3515#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_sub_ ##Type(obj, arg)
3516#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_or_ ##Type(obj, arg)
3517#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xor_ ##Type(obj, arg)
3518#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_and_ ##Type(obj, arg)
3519#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_nand_##Type(obj, arg)
3520#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_min_ ##Type(obj, arg)
3521#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg)
3522#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg)
3523#define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##Type(obj)
3524#if _M_X64
3525#define zig_fence(order) __faststorefence()
3526#else
3527#define zig_fence(order) zig_msvc_atomic_barrier()
3528#endif
3529/* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */
3530#else
3531#define memory_order_relaxed 0
3532#define memory_order_consume 1
3533#define memory_order_acquire 2
3534#define memory_order_release 3
3535#define memory_order_acq_rel 4
3536#define memory_order_seq_cst 5
3537#define zig_atomic(Type) Type
3538#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3539#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3540#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3541#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3542#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3543#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3544#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3545#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3546#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3547#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3548#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3549#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable
3550#define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable
3551#define zig_fence(order) zig_fence_unavailable
3552#endif
3553
3227#if _MSC_VER && (_M_IX86 || _M_X64)3554#if _MSC_VER && (_M_IX86 || _M_X64)
32283555
3229// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x643556/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
32303557
3231#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \3558#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \
3232 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \3559 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \
...@@ -3316,51 +3643,30 @@ zig_msvc_atomics(u64, uint64_t, __int64, 64)...@@ -3316,51 +3643,30 @@ zig_msvc_atomics(u64, uint64_t, __int64, 64)
3316zig_msvc_atomics(i64, int64_t, __int64, 64)3643zig_msvc_atomics(i64, int64_t, __int64, 64)
3317#endif3644#endif
33183645
3319#define zig_msvc_flt_atomics(Type, ReprType, suffix) \3646#define zig_msvc_flt_atomics(Type, SigType, suffix) \
3320 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \3647 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \
3321 ReprType exchange; \3648 SigType exchange; \
3322 ReprType comparand; \3649 SigType comparand; \
3323 ReprType initial; \3650 SigType initial; \
3324 bool success; \3651 bool success; \
3325 memcpy(&comparand, expected, sizeof(comparand)); \3652 memcpy(&comparand, expected, sizeof(comparand)); \
3326 memcpy(&exchange, &desired, sizeof(exchange)); \3653 memcpy(&exchange, &desired, sizeof(exchange)); \
3327 initial = _InterlockedCompareExchange##suffix((ReprType volatile*)obj, exchange, comparand); \3654 initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, exchange, comparand); \
3328 success = initial == comparand; \3655 success = initial == comparand; \
3329 if (!success) memcpy(expected, &initial, sizeof(*expected)); \3656 if (!success) memcpy(expected, &initial, sizeof(*expected)); \
3330 return success; \3657 return success; \
3331 } \3658 } \
3332 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \3659 static inline void zig_msvc_atomic_store_##Type(zig_##Type volatile* obj, zig_##Type arg) { \
3333 ReprType repr; \3660 SigType value; \
3334 ReprType initial; \3661 memcpy(&value, &arg, sizeof(value)); \
3662 (void)_InterlockedExchange##suffix((SigType volatile*)obj, value); \
3663 } \
3664 static inline zig_##Type zig_msvc_atomic_load_##Type(zig_##Type volatile* obj) { \
3335 zig_##Type result; \3665 zig_##Type result; \
3336 memcpy(&repr, &value, sizeof(repr)); \3666 SigType initial = _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \
3337 initial = _InterlockedExchange##suffix((ReprType volatile*)obj, repr); \
3338 memcpy(&result, &initial, sizeof(result)); \3667 memcpy(&result, &initial, sizeof(result)); \
3339 return result; \3668 return result; \
3340 } \
3341 static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3342 ReprType repr; \
3343 zig_##Type expected; \
3344 zig_##Type desired; \
3345 repr = *(ReprType volatile*)obj; \
3346 memcpy(&expected, &repr, sizeof(expected)); \
3347 do { \
3348 desired = expected + value; \
3349 } while (!zig_msvc_cmpxchg_##Type(obj, &expected, desired)); \
3350 return expected; \
3351 } \
3352 static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3353 ReprType repr; \
3354 zig_##Type expected; \
3355 zig_##Type desired; \
3356 repr = *(ReprType volatile*)obj; \
3357 memcpy(&expected, &repr, sizeof(expected)); \
3358 do { \
3359 desired = expected - value; \
3360 } while (!zig_msvc_cmpxchg_##Type(obj, &expected, desired)); \
3361 return expected; \
3362 }3669 }
3363
3364zig_msvc_flt_atomics(f32, long, )3670zig_msvc_flt_atomics(f32, long, )
3365#if _M_X643671#if _M_X64
3366zig_msvc_flt_atomics(f64, int64_t, 64)3672zig_msvc_flt_atomics(f64, int64_t, 64)
...@@ -3421,42 +3727,6 @@ static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expec...@@ -3421,42 +3727,6 @@ static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expec
3421static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {3727static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
3422 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);3728 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);
3423}3729}
3424
3425#define zig_msvc_atomics_128xchg(Type) \
3426 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3427 bool success = false; \
3428 zig_##Type prev; \
3429 while (!success) { \
3430 prev = *obj; \
3431 success = zig_msvc_cmpxchg_##Type(obj, &prev, value); \
3432 } \
3433 return prev; \
3434 }
3435
3436zig_msvc_atomics_128xchg(u128)
3437zig_msvc_atomics_128xchg(i128)
3438
3439#define zig_msvc_atomics_128op(Type, operation) \
3440 static inline zig_##Type zig_msvc_atomicrmw_##operation##_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3441 bool success = false; \
3442 zig_##Type new; \
3443 zig_##Type prev; \
3444 while (!success) { \
3445 prev = *obj; \
3446 new = zig_##operation##_##Type(prev, value); \
3447 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \
3448 } \
3449 return prev; \
3450 }
3451
3452zig_msvc_atomics_128op(u128, add)
3453zig_msvc_atomics_128op(u128, sub)
3454zig_msvc_atomics_128op(u128, or)
3455zig_msvc_atomics_128op(u128, xor)
3456zig_msvc_atomics_128op(u128, and)
3457zig_msvc_atomics_128op(u128, nand)
3458zig_msvc_atomics_128op(u128, min)
3459zig_msvc_atomics_128op(u128, max)
3460#endif /* _M_IX86 */3730#endif /* _M_IX86 */
34613731
3462#endif /* _MSC_VER && (_M_IX86 || _M_X64) */3732#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/cast.zig-1
...@@ -401,7 +401,6 @@ test "expected [*c]const u8, found [*:0]const u8" {...@@ -401,7 +401,6 @@ test "expected [*c]const u8, found [*:0]const u8" {
401}401}
402402
403test "explicit cast from integer to error type" {403test "explicit cast from integer to error type" {
404 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
405 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
406 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO405 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
407 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO406 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/eval.zig+12
...@@ -1649,3 +1649,15 @@ test "early exit in container level const" {...@@ -1649,3 +1649,15 @@ test "early exit in container level const" {
1649 };1649 };
1650 try expect(S.value == 1);1650 try expect(S.value == 1);
1651}1651}
1652
1653test "@inComptime" {
1654 const S = struct {
1655 fn inComptime() bool {
1656 return @inComptime();
1657 }
1658 };
1659 try expectEqual(false, @inComptime());
1660 try expectEqual(true, comptime @inComptime());
1661 try expectEqual(false, S.inComptime());
1662 try expectEqual(true, comptime S.inComptime());
1663}
test/behavior/fn.zig+17
...@@ -455,6 +455,23 @@ test "method call with optional and error union first param" {...@@ -455,6 +455,23 @@ test "method call with optional and error union first param" {
455 try s.errUnion();455 try s.errUnion();
456}456}
457457
458test "method call with optional pointer first param" {
459 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
460 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
461
462 const S = struct {
463 x: i32 = 1234,
464
465 fn method(s: ?*@This()) !void {
466 try expect(s.?.x == 1234);
467 }
468 };
469 var s: S = .{};
470 try s.method();
471 const s_ptr = &s;
472 try s_ptr.method();
473}
474
458test "using @ptrCast on function pointers" {475test "using @ptrCast on function pointers" {
459 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO476 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
460 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO477 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/type.zig+3-4
...@@ -486,10 +486,9 @@ test "Type.Union from regular enum" {...@@ -486,10 +486,9 @@ test "Type.Union from regular enum" {
486}486}
487487
488test "Type.Fn" {488test "Type.Fn" {
489 if (true) {489 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
490 // https://github.com/ziglang/zig/issues/12360490 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
491 return error.SkipZigTest;491 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
492 }
493492
494 const some_opaque = opaque {};493 const some_opaque = opaque {};
495 const some_ptr = *some_opaque;494 const some_ptr = *some_opaque;
test/cases/compile_errors/union_init_with_none_or_multiple_fields.zig+2-2
...@@ -29,10 +29,10 @@ export fn u2m() void {...@@ -29,10 +29,10 @@ export fn u2m() void {
29//29//
30// :9:1: error: union initializer must initialize one field30// :9:1: error: union initializer must initialize one field
31// :1:12: note: union declared here31// :1:12: note: union declared here
32// :14:20: error: cannot initialize multiple union fields at once, unions can only have one active field32// :14:20: error: cannot initialize multiple union fields at once; unions can only have one active field
33// :14:31: note: additional initializer here33// :14:31: note: additional initializer here
34// :1:12: note: union declared here34// :1:12: note: union declared here
35// :18:21: error: union initializer must initialize one field35// :18:21: error: union initializer must initialize one field
36// :22:20: error: cannot initialize multiple union fields at once, unions can only have one active field36// :22:20: error: cannot initialize multiple union fields at once; unions can only have one active field
37// :22:31: note: additional initializer here37// :22:31: note: additional initializer here
38// :5:12: note: union declared here38// :5:12: note: union declared here
test/cases/compile_errors/variadic_arg_validation.zig+1-1
...@@ -21,7 +21,7 @@ pub export fn entry3() void {...@@ -21,7 +21,7 @@ pub export fn entry3() void {
21// backend=stage221// backend=stage2
22// target=native22// target=native
23//23//
24// :4:33: error: integer and float literals passed variadic function must be casted to a fixed-size number type24// :4:33: error: integer and float literals passed to variadic function must be casted to a fixed-size number type
25// :9:24: error: arrays must be passed by reference to variadic function25// :9:24: error: arrays must be passed by reference to variadic function
26// :13:24: error: cannot pass 'u48' to variadic function26// :13:24: error: cannot pass 'u48' to variadic function
27// :13:24: note: only integers with power of two bits are extern compatible27// :13:24: note: only integers with power of two bits are extern compatible
test/cases/safety/pointer casting to null function pointer.zig created+23
...@@ -0,0 +1,23 @@
1const std = @import("std");
2
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
4 _ = stack_trace;
5 if (std.mem.eql(u8, message, "cast causes pointer to be null")) {
6 std.process.exit(0);
7 }
8 std.process.exit(1);
9}
10
11fn getNullPtr() ?*const anyopaque {
12 return null;
13}
14pub fn main() !void {
15 const null_ptr: ?*const anyopaque = getNullPtr();
16 const required_ptr: *align(1) const fn() void = @ptrCast(*align(1) const fn() void, null_ptr);
17 _ = required_ptr;
18 return error.TestFailed;
19}
20
21// run
22// backend=llvm
23// target=native
test/tests.zig+6
...@@ -1040,6 +1040,12 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {...@@ -1040,6 +1040,12 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
1040 });1040 });
1041 compile_c.addIncludePath("lib"); // for zig.h1041 compile_c.addIncludePath("lib"); // for zig.h
1042 if (test_target.target.getOsTag() == .windows) {1042 if (test_target.target.getOsTag() == .windows) {
1043 if (true) {
1044 // Unfortunately this requires about 8G of RAM for clang to compile
1045 // and our Windows CI runners do not have this much.
1046 step.dependOn(&these_tests.step);
1047 continue;
1048 }
1043 if (test_target.link_libc == false) {1049 if (test_target.link_libc == false) {
1044 compile_c.subsystem = .Console;1050 compile_c.subsystem = .Console;
1045 compile_c.linkSystemLibrary("kernel32");1051 compile_c.linkSystemLibrary("kernel32");
test/translate_c.zig+6
...@@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3956 \\ .name = "foo",3956 \\ .name = "foo",
3957 \\});3957 \\});
3958 });3958 });
3959
3960 cases.add("string array initializer",
3961 \\static const char foo[] = {"bar"};
3962 , &[_][]const u8{
3963 \\pub const foo: [3:0]u8 = "bar";
3964 });
3959}3965}