| author | |
| committer | |
| log | 015ea6fd6c0c0deacb42de237f737d208737e3ac |
| tree | 33f5e2d3acacc24e63f259ce5485fee28243ed44 |
| parent | a260fa8bf22b952e96b08c3f206756e1784ce870 |
| parent | 8d88dcdc61c61e3410138f4402482131f5074a80 |
| signature |
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 { |
| 1422 | 1422 | ||
| 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 the | 1424 | <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#} |
| 1427 | const std = @import("std"); | 1428 | const std = @import("std"); |
| 1428 | const assert = std.debug.assert; | 1429 | const assert = std.debug.assert; |
| ... | @@ -4278,7 +4279,7 @@ const expectError = std.testing.expectError; | ... | @@ -4278,7 +4279,7 @@ const expectError = std.testing.expectError; |
| 4278 | fn isFieldOptional(comptime T: type, field_index: usize) !bool { | 4279 | fn 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 an | 4282 | // 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 | |||
| 4681 | test "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 | } |
| 4671 | 4695 | ||
| 4672 | test "for reference" { | 4696 | test "for reference" { |
| ... | @@ -4710,8 +4734,8 @@ const expect = std.testing.expect; | ... | @@ -4710,8 +4734,8 @@ const expect = std.testing.expect; |
| 4710 | 4734 | ||
| 4711 | test "nested break" { | 4735 | test "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" { |
| 4721 | 4745 | ||
| 4722 | test "nested continue" { | 4746 | test "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#} |
| 8565 | 8589 | ||
| 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" { |
| 8812 | pub const PrefetchOptions = struct { | 8849 | pub 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 immediately | 8854 | /// 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, |
| 8823 | 8862 | ||
| 8824 | pub const Rw = enum { | 8863 | pub const Rw = enum(u1) { |
| 8825 | read, | 8864 | read, |
| 8826 | write, | 8865 | write, |
| 8827 | }; | 8866 | }; |
| 8828 | 8867 | ||
| 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-checked | 10992 | 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 { |
| 184 | pub const HashHelper = struct { | 184 | pub const HashHelper = struct { |
| 185 | hasher: Hasher = hasher_init, | 185 | hasher: Hasher = hasher_init, |
| 186 | 186 | ||
| 187 | /// Record a slice of bytes as an dependency of the process being cached | 187 | /// 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 utilise | 1 | //! 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's | 2 | //! 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. This | 3 | //! 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 by | 4 | //! 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 adding | 5 | //! 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. |
| 3 | 3 | ||
| 4 | const Uri = @This(); | 4 | const 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(); |
| 240 | 242 |
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; |
| 35 | const Allocator = std.mem.Allocator; | 35 | const Allocator = std.mem.Allocator; |
| 36 | 36 | ||
| 37 | /// Returns the optimal static bit set type for the specified number | 37 | /// 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. | ||
| 41 | pub fn StaticBitSet(comptime size: usize) type { | 42 | pub 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 and | 144 | /// 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. |
| 146 | pub const CallingConvention = enum { | 146 | pub 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 | }; |
| 165 | 190 | ||
| ... | @@ -716,6 +741,8 @@ pub const VaList = switch (builtin.cpu.arch) { | ... | @@ -716,6 +741,8 @@ pub const VaList = switch (builtin.cpu.arch) { |
| 716 | pub const PrefetchOptions = struct { | 741 | pub 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 immediately | 746 | /// 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 |
| 3846 | pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void; | 3846 | pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void; |
| 3847 | pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t; | 3847 | pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t; |
| 3848 | pub extern "c" fn os_signpost_enabled(log: os_log_t) bool; | 3848 | pub extern "c" fn os_signpost_enabled(log: os_log_t) bool; |
| 3849 | |||
| 3850 | pub extern "c" fn proc_listpids(tpe: u32, tinfo: u32, buffer: ?*anyopaque, buffersize: c_int) c_int; | ||
| 3851 | pub extern "c" fn proc_listallpids(buffer: ?*anyopaque, buffersize: c_int) c_int; | ||
| 3852 | pub extern "c" fn proc_listpgrppids(pgrpid: pid_t, buffer: ?*anyopaque, buffersize: c_int) c_int; | ||
| 3853 | pub extern "c" fn proc_listchildpids(ppid: pid_t, buffer: ?*anyopaque, buffersize: c_int) c_int; | ||
| 3854 | pub extern "c" fn proc_pidinfo(pid: c_int, flavor: c_int, arg: u64, buffer: ?*anyopaque, buffersize: c_int) c_int; | ||
| 3855 | pub extern "c" fn proc_name(pid: c_int, buffer: ?*anyopaque, buffersize: u32) c_int; | ||
| 3856 | pub 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 | |||
| 1147 | pub const SIGEV = struct { | ||
| 1148 | pub const NONE = 0; | ||
| 1149 | pub const SIGNAL = 1; | ||
| 1150 | pub const THREAD = 2; | ||
| 1151 | }; | ||
| 1152 | |||
| 1153 | pub 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; |
| 29 | extern "c" fn __error() *c_int; | 29 | extern "c" fn __error() *c_int; |
| 30 | pub const _errno = __error; | 30 | pub const _errno = __error; |
| 31 | 31 | ||
| 32 | pub extern "c" var malloc_options: [*:0]const u8; | ||
| 33 | |||
| 32 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; | 34 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; |
| 33 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; | 35 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
| 34 | pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; | 36 | pub 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; |
| 42 | 44 | ||
| 43 | pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; | 45 | pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; |
| 44 | pub extern "c" fn malloc_usable_size(?*const anyopaque) usize; | 46 | pub extern "c" fn malloc_usable_size(?*const anyopaque) usize; |
| 47 | pub extern "c" fn reallocf(?*anyopaque, usize) ?*anyopaque; | ||
| 45 | 48 | ||
| 46 | pub extern "c" fn getpid() pid_t; | 49 | pub extern "c" fn getpid() pid_t; |
| 47 | 50 | ||
| ... | @@ -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; |
| 50 | 53 | ||
| 51 | pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int; | 54 | pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int; |
| 52 | pub extern "c" fn cpuset_setaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *const cpuset_t) c_int; | 55 | pub extern "c" fn cpuset_setaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *const cpuset_t) c_int; |
| 56 | pub extern "c" fn sched_getaffinity(pid: pid_t, cpusetsz: usize, cpuset: *cpuset_t) c_int; | ||
| 57 | pub extern "c" fn sched_setaffinity(pid: pid_t, cpusetsz: usize, cpuset: *const cpuset_t) c_int; | ||
| 58 | pub extern "c" fn sched_getcpu() c_int; | ||
| 53 | 59 | ||
| 54 | pub const sf_hdtr = extern struct { | 60 | pub 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 | }; |
| 1104 | 1110 | ||
| 1111 | pub 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) |
| 1106 | pub const EV_ADD = 0x0001; | 1117 | pub const EV_ADD = 0x0001; |
| 1107 | 1118 | ||
| ... | @@ -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 { |
| 2205 | pub 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; | 2248 | pub 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; |
| 2206 | 2249 | ||
| 2207 | pub extern "c" fn elf_aux_info(aux: c_int, buf: ?*anyopaque, buflen: c_int) c_int; | 2250 | pub extern "c" fn elf_aux_info(aux: c_int, buf: ?*anyopaque, buflen: c_int) c_int; |
| 2251 | |||
| 2252 | pub const lwpid = i32; | ||
| 2253 | |||
| 2254 | pub 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 | |||
| 2262 | pub 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 | |||
| 2277 | pub 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 | |||
| 2289 | pub 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; |
| 5 | const iovec = std.os.iovec; | 5 | const iovec = std.os.iovec; |
| 6 | const iovec_const = std.os.iovec_const; | 6 | const iovec_const = std.os.iovec_const; |
| 7 | 7 | ||
| 8 | const status_t = i32; | ||
| 9 | |||
| 8 | extern "c" fn _errnop() *c_int; | 10 | extern "c" fn _errnop() *c_int; |
| 9 | 11 | ||
| 10 | pub const _errno = _errnop; | 12 | pub const _errno = _errnop; |
| 11 | 13 | ||
| 12 | pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64; | 14 | pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) status_t; |
| 15 | |||
| 16 | pub extern "c" fn find_path(codePointer: *const u8, baseDirectory: c_int, subPath: [*:0]const u8, pathBuffer: [*:0]u8, bufferSize: usize) status_t; | ||
| 13 | 17 | ||
| 14 | pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32; | 18 | pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32; |
| 15 | 19 | ||
| ... | @@ -1038,3 +1042,22 @@ pub const termios = extern struct { | ... | @@ -1038,3 +1042,22 @@ pub const termios = extern struct { |
| 1038 | }; | 1042 | }; |
| 1039 | 1043 | ||
| 1040 | pub const MSG_NOSIGNAL = 0x0800; | 1044 | pub const MSG_NOSIGNAL = 0x0800; |
| 1045 | |||
| 1046 | pub const SIGEV = struct { | ||
| 1047 | pub const NONE = 0; | ||
| 1048 | pub const SIGNAL = 1; | ||
| 1049 | pub const THREAD = 2; | ||
| 1050 | }; | ||
| 1051 | |||
| 1052 | pub const sigval = extern union { | ||
| 1053 | int: c_int, | ||
| 1054 | ptr: ?*anyopaque, | ||
| 1055 | }; | ||
| 1056 | |||
| 1057 | pub 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 | |||
| 1637 | pub const SIGEV = struct { | ||
| 1638 | pub const NONE = 0; | ||
| 1639 | pub const SIGNAL = 1; | ||
| 1640 | pub const THREAD = 2; | ||
| 1641 | }; | ||
| 1642 | |||
| 1643 | pub const sigval = extern union { | ||
| 1644 | int: c_int, | ||
| 1645 | ptr: ?*anyopaque, | ||
| 1646 | }; | ||
| 1647 | |||
| 1648 | pub 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 { |
| 1927 | pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 { | 1927 | pub 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 | |||
| 1931 | pub const SIGEV = struct { | ||
| 1932 | pub const NONE = 0; | ||
| 1933 | pub const SIGNAL = 1; | ||
| 1934 | pub const THREAD = 2; | ||
| 1935 | }; | ||
| 1936 | |||
| 1937 | pub const sigval = extern union { | ||
| 1938 | int: c_int, | ||
| 1939 | ptr: ?*anyopaque, | ||
| 1940 | }; | ||
| 1941 | |||
| 1942 | pub 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"); |
| 10 | 10 | ||
| 11 | pub const DecompressStreamOptions = struct { | 11 | pub 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 | }; |
| 15 | 15 | ||
| 16 | pub fn DecompressStream( | 16 | pub 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; |
| 22 | 22 | ||
| 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{ |
| 71 | 71 | ||
| 72 | const v4u32 = @Vector(4, u32); | 72 | const v4u32 = @Vector(4, u32); |
| 73 | 73 | ||
| 74 | // TODO: Remove once https://github.com/ziglang/zig/issues/868 is resolved. | ||
| 75 | fn isComptime() bool { | ||
| 76 | var a: u8 = 0; | ||
| 77 | return @typeInfo(@TypeOf(.{a})).Struct.fields[0].is_comptime; | ||
| 78 | } | ||
| 79 | |||
| 80 | /// SHA-224 | 74 | /// SHA-224 |
| 81 | pub const Sha224 = Sha2x32(Sha224Params); | 75 | pub const Sha224 = Sha2x32(Sha224Params); |
| 82 | 76 | ||
| ... | @@ -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 | } |
| 205 | 199 | ||
| 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 | } |
| 653 | 653 | ||
| 654 | /// Provides simple functionality for manipulating the terminal in some way, | ||
| 655 | /// for debugging purposes, such as coloring text, etc. | ||
| 654 | pub const TTY = struct { | 656 | pub 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; |
| 221 | 221 | ||
| 222 | pub const DT_NIOS2_GP = 0x70000002; | 222 | pub const DT_NIOS2_GP = 0x70000002; |
| 223 | 223 | ||
| 224 | /// Program header table entry unused | ||
| 224 | pub const PT_NULL = 0; | 225 | pub const PT_NULL = 0; |
| 226 | /// Loadable program segment | ||
| 225 | pub const PT_LOAD = 1; | 227 | pub const PT_LOAD = 1; |
| 228 | /// Dynamic linking information | ||
| 226 | pub const PT_DYNAMIC = 2; | 229 | pub const PT_DYNAMIC = 2; |
| 230 | /// Program interpreter | ||
| 227 | pub const PT_INTERP = 3; | 231 | pub const PT_INTERP = 3; |
| 232 | /// Auxiliary information | ||
| 228 | pub const PT_NOTE = 4; | 233 | pub const PT_NOTE = 4; |
| 234 | /// Reserved | ||
| 229 | pub const PT_SHLIB = 5; | 235 | pub const PT_SHLIB = 5; |
| 236 | /// Entry for header table itself | ||
| 230 | pub const PT_PHDR = 6; | 237 | pub const PT_PHDR = 6; |
| 238 | /// Thread-local storage segment | ||
| 231 | pub const PT_TLS = 7; | 239 | pub const PT_TLS = 7; |
| 240 | /// Number of defined types | ||
| 232 | pub const PT_NUM = 8; | 241 | pub const PT_NUM = 8; |
| 242 | /// Start of OS-specific | ||
| 233 | pub const PT_LOOS = 0x60000000; | 243 | pub const PT_LOOS = 0x60000000; |
| 244 | /// GCC .eh_frame_hdr segment | ||
| 234 | pub const PT_GNU_EH_FRAME = 0x6474e550; | 245 | pub const PT_GNU_EH_FRAME = 0x6474e550; |
| 246 | /// Indicates stack executability | ||
| 235 | pub const PT_GNU_STACK = 0x6474e551; | 247 | pub const PT_GNU_STACK = 0x6474e551; |
| 248 | /// Read-only after relocation | ||
| 236 | pub const PT_GNU_RELRO = 0x6474e552; | 249 | pub const PT_GNU_RELRO = 0x6474e552; |
| 237 | pub const PT_LOSUNW = 0x6ffffffa; | 250 | pub const PT_LOSUNW = 0x6ffffffa; |
| 251 | /// Sun specific segment | ||
| 238 | pub const PT_SUNWBSS = 0x6ffffffa; | 252 | pub const PT_SUNWBSS = 0x6ffffffa; |
| 253 | /// Stack segment | ||
| 239 | pub const PT_SUNWSTACK = 0x6ffffffb; | 254 | pub const PT_SUNWSTACK = 0x6ffffffb; |
| 240 | pub const PT_HISUNW = 0x6fffffff; | 255 | pub const PT_HISUNW = 0x6fffffff; |
| 256 | /// End of OS-specific | ||
| 241 | pub const PT_HIOS = 0x6fffffff; | 257 | pub const PT_HIOS = 0x6fffffff; |
| 258 | /// Start of processor-specific | ||
| 242 | pub const PT_LOPROC = 0x70000000; | 259 | pub const PT_LOPROC = 0x70000000; |
| 260 | /// End of processor-specific | ||
| 243 | pub const PT_HIPROC = 0x7fffffff; | 261 | pub const PT_HIPROC = 0x7fffffff; |
| 244 | 262 | ||
| 263 | /// Section header table entry unused | ||
| 245 | pub const SHT_NULL = 0; | 264 | pub const SHT_NULL = 0; |
| 265 | /// Program data | ||
| 246 | pub const SHT_PROGBITS = 1; | 266 | pub const SHT_PROGBITS = 1; |
| 267 | /// Symbol table | ||
| 247 | pub const SHT_SYMTAB = 2; | 268 | pub const SHT_SYMTAB = 2; |
| 269 | /// String table | ||
| 248 | pub const SHT_STRTAB = 3; | 270 | pub const SHT_STRTAB = 3; |
| 271 | /// Relocation entries with addends | ||
| 249 | pub const SHT_RELA = 4; | 272 | pub const SHT_RELA = 4; |
| 273 | /// Symbol hash table | ||
| 250 | pub const SHT_HASH = 5; | 274 | pub const SHT_HASH = 5; |
| 275 | /// Dynamic linking information | ||
| 251 | pub const SHT_DYNAMIC = 6; | 276 | pub const SHT_DYNAMIC = 6; |
| 277 | /// Notes | ||
| 252 | pub const SHT_NOTE = 7; | 278 | pub const SHT_NOTE = 7; |
| 279 | /// Program space with no data (bss) | ||
| 253 | pub const SHT_NOBITS = 8; | 280 | pub const SHT_NOBITS = 8; |
| 281 | /// Relocation entries, no addends | ||
| 254 | pub const SHT_REL = 9; | 282 | pub const SHT_REL = 9; |
| 283 | /// Reserved | ||
| 255 | pub const SHT_SHLIB = 10; | 284 | pub const SHT_SHLIB = 10; |
| 285 | /// Dynamic linker symbol table | ||
| 256 | pub const SHT_DYNSYM = 11; | 286 | pub const SHT_DYNSYM = 11; |
| 287 | /// Array of constructors | ||
| 257 | pub const SHT_INIT_ARRAY = 14; | 288 | pub const SHT_INIT_ARRAY = 14; |
| 289 | /// Array of destructors | ||
| 258 | pub const SHT_FINI_ARRAY = 15; | 290 | pub const SHT_FINI_ARRAY = 15; |
| 291 | /// Array of pre-constructors | ||
| 259 | pub const SHT_PREINIT_ARRAY = 16; | 292 | pub const SHT_PREINIT_ARRAY = 16; |
| 293 | /// Section group | ||
| 260 | pub const SHT_GROUP = 17; | 294 | pub const SHT_GROUP = 17; |
| 295 | /// Extended section indices | ||
| 261 | pub const SHT_SYMTAB_SHNDX = 18; | 296 | pub const SHT_SYMTAB_SHNDX = 18; |
| 297 | /// Start of OS-specific | ||
| 262 | pub const SHT_LOOS = 0x60000000; | 298 | pub const SHT_LOOS = 0x60000000; |
| 299 | /// End of OS-specific | ||
| 263 | pub const SHT_HIOS = 0x6fffffff; | 300 | pub const SHT_HIOS = 0x6fffffff; |
| 301 | /// Start of processor-specific | ||
| 264 | pub const SHT_LOPROC = 0x70000000; | 302 | pub const SHT_LOPROC = 0x70000000; |
| 303 | /// End of processor-specific | ||
| 265 | pub const SHT_HIPROC = 0x7fffffff; | 304 | pub const SHT_HIPROC = 0x7fffffff; |
| 305 | /// Start of application-specific | ||
| 266 | pub const SHT_LOUSER = 0x80000000; | 306 | pub const SHT_LOUSER = 0x80000000; |
| 307 | /// End of application-specific | ||
| 267 | pub const SHT_HIUSER = 0xffffffff; | 308 | pub const SHT_HIUSER = 0xffffffff; |
| 268 | 309 | ||
| 310 | /// Local symbol | ||
| 269 | pub const STB_LOCAL = 0; | 311 | pub const STB_LOCAL = 0; |
| 312 | /// Global symbol | ||
| 270 | pub const STB_GLOBAL = 1; | 313 | pub const STB_GLOBAL = 1; |
| 314 | /// Weak symbol | ||
| 271 | pub const STB_WEAK = 2; | 315 | pub const STB_WEAK = 2; |
| 316 | /// Number of defined types | ||
| 272 | pub const STB_NUM = 3; | 317 | pub const STB_NUM = 3; |
| 318 | /// Start of OS-specific | ||
| 273 | pub const STB_LOOS = 10; | 319 | pub const STB_LOOS = 10; |
| 320 | /// Unique symbol | ||
| 274 | pub const STB_GNU_UNIQUE = 10; | 321 | pub const STB_GNU_UNIQUE = 10; |
| 322 | /// End of OS-specific | ||
| 275 | pub const STB_HIOS = 12; | 323 | pub const STB_HIOS = 12; |
| 324 | /// Start of processor-specific | ||
| 276 | pub const STB_LOPROC = 13; | 325 | pub const STB_LOPROC = 13; |
| 326 | /// End of processor-specific | ||
| 277 | pub const STB_HIPROC = 15; | 327 | pub const STB_HIPROC = 15; |
| 278 | 328 | ||
| 279 | pub const STB_MIPS_SPLIT_COMMON = 13; | 329 | pub const STB_MIPS_SPLIT_COMMON = 13; |
| 280 | 330 | ||
| 331 | /// Symbol type is unspecified | ||
| 281 | pub const STT_NOTYPE = 0; | 332 | pub const STT_NOTYPE = 0; |
| 333 | /// Symbol is a data object | ||
| 282 | pub const STT_OBJECT = 1; | 334 | pub const STT_OBJECT = 1; |
| 335 | /// Symbol is a code object | ||
| 283 | pub const STT_FUNC = 2; | 336 | pub const STT_FUNC = 2; |
| 337 | /// Symbol associated with a section | ||
| 284 | pub const STT_SECTION = 3; | 338 | pub const STT_SECTION = 3; |
| 339 | /// Symbol's name is file name | ||
| 285 | pub const STT_FILE = 4; | 340 | pub const STT_FILE = 4; |
| 341 | /// Symbol is a common data object | ||
| 286 | pub const STT_COMMON = 5; | 342 | pub const STT_COMMON = 5; |
| 343 | /// Symbol is thread-local data object | ||
| 287 | pub const STT_TLS = 6; | 344 | pub const STT_TLS = 6; |
| 345 | /// Number of defined types | ||
| 288 | pub const STT_NUM = 7; | 346 | pub const STT_NUM = 7; |
| 347 | /// Start of OS-specific | ||
| 289 | pub const STT_LOOS = 10; | 348 | pub const STT_LOOS = 10; |
| 349 | /// Symbol is indirect code object | ||
| 290 | pub const STT_GNU_IFUNC = 10; | 350 | pub const STT_GNU_IFUNC = 10; |
| 351 | /// End of OS-specific | ||
| 291 | pub const STT_HIOS = 12; | 352 | pub const STT_HIOS = 12; |
| 353 | /// Start of processor-specific | ||
| 292 | pub const STT_LOPROC = 13; | 354 | pub const STT_LOPROC = 13; |
| 355 | /// End of processor-specific | ||
| 293 | pub const STT_HIPROC = 15; | 356 | pub const STT_HIPROC = 15; |
| 294 | 357 | ||
| 295 | pub const STT_SPARC_REGISTER = 13; | 358 | pub 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 | }; |
| 660 | pub const Elf64_Sym = extern struct { | 730 | pub 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 | }; |
| 668 | pub const Elf32_Syminfo = extern struct { | 745 | pub 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 | }; |
| 687 | pub const Elf64_Rel = extern struct { | 764 | pub 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 | }; |
| 698 | pub const Elf32_Rela = extern struct { | 775 | pub 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 | }; |
| 710 | pub const Elf64_Rela = extern struct { | 787 | pub 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 | }; |
| 722 | pub const Elf32_Dyn = extern struct { | 799 | pub 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. |
| 1631 | pub const PF_MASKPROC = 0xf0000000; | 1708 | pub const PF_MASKPROC = 0xf0000000; |
| 1632 | 1709 | ||
| 1633 | // Special section indexes used in Elf{32,64}_Sym. | 1710 | /// Undefined section |
| 1634 | pub const SHN_UNDEF = 0; | 1711 | pub const SHN_UNDEF = 0; |
| 1712 | /// Start of reserved indices | ||
| 1635 | pub const SHN_LORESERVE = 0xff00; | 1713 | pub const SHN_LORESERVE = 0xff00; |
| 1714 | /// Start of processor-specific | ||
| 1636 | pub const SHN_LOPROC = 0xff00; | 1715 | pub const SHN_LOPROC = 0xff00; |
| 1716 | /// End of processor-specific | ||
| 1637 | pub const SHN_HIPROC = 0xff1f; | 1717 | pub const SHN_HIPROC = 0xff1f; |
| 1638 | pub const SHN_LIVEPATCH = 0xff20; | 1718 | pub const SHN_LIVEPATCH = 0xff20; |
| 1719 | /// Associated symbol is absolute | ||
| 1639 | pub const SHN_ABS = 0xfff1; | 1720 | pub const SHN_ABS = 0xfff1; |
| 1721 | /// Associated symbol is common | ||
| 1640 | pub const SHN_COMMON = 0xfff2; | 1722 | pub const SHN_COMMON = 0xfff2; |
| 1723 | /// End of reserved indices | ||
| 1641 | pub const SHN_HIRESERVE = 0xffff; | 1724 | pub const SHN_HIRESERVE = 0xffff; |
| 1642 | 1725 | ||
| 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 text | 43 | /// - *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* aligned | 44 | /// - *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 characters | 45 | /// - *width* is the total width of the field in characters |
| 46 | /// - *precision* specifies how many decimals a formatted number should have | 46 | /// - *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; |
| 1430 | 1430 | ||
| 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 | } |
| 1471 | 1470 | ||
| 1472 | // TODO: Remove once https://github.com/ziglang/zig/issues/868 is resolved. | ||
| 1473 | fn isComptime() bool { | ||
| 1474 | var a: u8 = 0; | ||
| 1475 | return @typeInfo(@TypeOf(.{a})).Struct.fields[0].is_comptime; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) usize { | 1471 | pub 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 | }; |
| 2216 | 2218 | ||
| ... | @@ -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; |
| 2918 | 2921 | ||
| ... | @@ -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 it | 3006 | // 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 | } |
| 1216 | 1216 | ||
| 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 | } |
| 647 | 647 | ||
| 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); |
| 650 | 649 | ||
| 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 | } |
| 766 | 765 | ||
| 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(); |
| 769 | 768 | ||
| 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 { |
| 797 | 796 | ||
| 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"); |
| 805 | 804 | ||
| 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; |
| 810 | 809 | ||
| 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 | } |
| 69 | 69 | ||
| 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); |
| 84 | 74 | ||
| ... | @@ -255,6 +245,39 @@ pub const Headers = struct { | ... | @@ -255,6 +245,39 @@ pub const Headers = struct { |
| 255 | 245 | ||
| 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 | }; |
| 259 | 282 | ||
| 260 | test "Headers.append" { | 283 | test "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 | |||
| 411 | test "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, |
| 338 | 338 | ||
| 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 { |
| 656 | 661 | ||
| 657 | return res; | 662 | return res; |
| 658 | } | 663 | } |
| 664 | |||
| 665 | test "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; |
| 562 | 566 | ||
| 563 | return out_index; | 567 | return out_index; |
lib/std/http/test.zig created+72| ... | @@ -0,0 +1,72 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | |||
| 4 | test "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 | }; |
| 542 | 542 | ||
| 543 | /// Dynamicaly linked shared libraries are identified by two things. The | 543 | /// Dynamically linked shared libraries are identified by two things. The |
| 544 | /// pathname (the name of the library as found for execution), and the | 544 | /// pathname (the name of the library as found for execution), and the |
| 545 | /// compatibility version number. The pathname must match and the compatibility | 545 | /// 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 the | 546 | /// 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 was | 547 | /// 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 used | 548 | /// 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. |
| 550 | pub const dylib = extern struct { | 550 | pub 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 | } |
| 783 | 783 | ||
| 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. | ||
| 786 | pub fn absInt(x: anytype) !@TypeOf(x) { | 787 | pub 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 | } |
| 1016 | 1017 | ||
| 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. |
| 1020 | pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) { | 1021 | pub 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 this | 227 | /// 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. |
| 231 | pub fn zeroes(comptime T: type) T { | 231 | pub 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, | ||
| 1870 | 1871 | ||
| 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 { |
| 1881 | 1882 | ||
| 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 | }; |
| 1885 | 1889 | ||
| 1886 | /// After this call succeeds, resources have been acquired and must | 1890 | /// 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 | } | ||
| 1923 | 1936 | ||
| 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 | } |
| 232 | 232 | ||
| 233 | test "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 | |||
| 233 | fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void { | 254 | fn 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; |
| 235 | 256 |
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 panic | 4726 | @compileError("unsupported OS"); |
| 4727 | } | ||
| 4728 | if (builtin.os.tag == .haiku) { | ||
| 4729 | @panic("unsupported"); // TODO should be compile error, not panic | ||
| 4730 | } | 4727 | } |
| 4731 | 4728 | ||
| 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 panic | 4748 | @compileError("unsupported OS"); |
| 4752 | } | ||
| 4753 | if (builtin.os.tag == .haiku) { | ||
| 4754 | @panic("unsupported"); // TODO should be compile error, not panic | ||
| 4755 | } | 4749 | } |
| 4756 | 4750 | ||
| 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; | ||
| 3468 | 3471 | ||
| 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 and | 21 | //! 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 arguments | 22 | //! 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 documentation | 24 | //! filters cannot be assumed to be portable without consulting documentation |
| 25 | //! like syscalls(2) and testing on target hardware. This also requires | 25 | //! 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 compiled | 26 | //! 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(); |
| 1102 | 1102 | ||
| 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 | } |
| 1106 | 1108 |
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 | }; |
| 820 | 820 | ||
| 821 | /// Use argsWithAllocator() for cross-platform code | 821 | /// Holds the command-line arguments, with the program name as the first entry. |
| 822 | /// Use argsWithAllocator() for cross-platform code. | ||
| 822 | pub fn args() ArgIterator { | 823 | pub 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 { |
| 389 | 389 | ||
| 390 | /// Randomly selects an index into `proportions`, where the likelihood of each | 390 | /// 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); |
| 131 | 131 | ||
| 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(); |
| 134 | 137 |
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, |
| 683 | 683 | ||
| 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, |
| 687 | 687 |
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); |
| 841 | 841 | ||
| 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); |
| 856 | 853 | ||
| 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); |
| 874 | 868 | ||
| 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); |
| 916 | 907 | ||
| 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); | ||
| 921 | 910 | ||
| 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); |
| 926 | 915 | ||
| 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); | ||
| 931 | 918 | ||
| 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( |
| 3330 | 3317 | ||
| 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); |
| 3332 | 3319 | ||
| 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); |
| 3346 | 3327 | ||
| 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; | ||
| 5365 | 5345 | ||
| 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); |
| 5387 | 5367 | ||
| 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); |
| 5609 | 5589 | ||
| 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); | ||
| 5614 | 5592 | ||
| 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); |
| 5632 | 5610 | ||
| 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; | ||
| 5636 | 5612 | ||
| 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); |
| 5639 | 5615 | ||
| 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); |
| 5644 | 5620 | ||
| 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; | ||
| 5648 | 5622 | ||
| 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); |
| 5651 | 5625 | ||
| 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 | } |
| 5675 | 5649 | ||
| 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); |
| 5688 | 5656 | ||
| 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 | } |
| 6788 | 6756 | ||
| 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; | ||
| 7159 | 7127 | ||
| 7160 | const defer_outer = &astgen.fn_block.?.base; | 7128 | const defer_outer = &astgen.fn_block.?.base; |
| 7161 | 7129 | ||
| ... | @@ -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 needed | 7178 | // 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); |
| 7212 | 7180 | ||
| 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); |
| 7231 | 7199 | ||
| 7232 | // As our last action before the return, "pop" the error trace if needed | 7200 | // 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 needed | 7218 | // 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); |
| 7252 | 7220 | ||
| 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); |
| 7255 | 7223 | ||
| 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); |
| 7265 | 7233 | ||
| 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), | ||
| 8177 | 8146 | ||
| 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); | ||
| 8653 | 8624 | ||
| 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 | else | 8658 | 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); | ||
| 8763 | 8738 | ||
| 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 | } |
| 8770 | 8743 | ||
| ... | @@ -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); |
| 8819 | 8790 | ||
| 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 | } | ||
| 8828 | 8795 | ||
| 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); |
| 8831 | 8798 | ||
| 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 | } |
| 12595 | 12566 | ||
| 12567 | const 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`. |
| 12598 | fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void { | 12571 | fn 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 }; |
| 12600 | 12573 | ||
| 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 | } |
| 12607 | 12582 | ||
| 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 | } |
| 12808 | 12783 | ||
| 12809 | fn emitDbgStmt(gz: *GenZir, line: u32, column: u32) !void { | 12784 | fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void { |
| 12810 | if (gz.is_comptime) return; | 12785 | if (gz.is_comptime) return; |
| 12811 | 12786 | ||
| 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 | }; |
| 4078 | 4078 | ||
| 4079 | // if we're analyzing a funcion signature (ie without body), we | 4079 | // if we're analyzing a function signature (ie without body), we |
| 4080 | // actually don't have an ast_node reserved for us, but since | 4080 | // 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 | }; |
| 4231 | 4231 | ||
| 4232 | // if we're analyzing a funcion signature (ie without body), we | 4232 | // if we're analyzing a function signature (ie without body), we |
| 4233 | // actually don't have an ast_node reserved for us, but since | 4233 | // 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: on | 1170 | // zig fmt: on |
| 1170 | 1171 | ||
| 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 | } |
| 19627 | 19628 | ||
| 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 |
| 19852 | 19853 | ||
| 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() and | 19855 | 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 | } |
| 22468 | 22469 | ||
| 22470 | fn 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 | |||
| 22469 | fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void { | 22482 | fn 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: off | 23754 | // zig fmt: off |
| 23743 | if (first_param_tag == .var_args_param or | 23755 | 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 and | 23779 | } 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 and | 23789 | 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() and | 27744 | 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, | ||
| 2021 | 2024 | ||
| 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), |
| 1948 | 1948 | ||
| 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 { |
| 3338 | fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3339 | fn 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 }; | ||
| 3341 | 3344 | ||
| 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 | } |
| 3345 | 3351 | ||
| 3346 | fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3352 | fn 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 | |||
| 6520 | fn 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 { |
| 460 | 460 | ||
| 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 | }; |
| 464 | 467 | ||
| 465 | pub const FieldDecl = opaque { | 468 | pub 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; |
| 1055 | 1058 | ||
| 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; |
| 1058 | 1067 |
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.html | 2 | //! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html |
| 3 | //! For this we rely on the nvptx backend of LLVM | 3 | //! 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 | } |
| 1213 | 1218 | ||
| 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 | } |
| 2187 | 2192 | ||
| 2193 | /// Generates an atom containing the global error set' size. | ||
| 2194 | /// This will only be generated if the symbol exists. | ||
| 2195 | fn 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 them | 2231 | /// 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 update | 3359 | // 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 for | 403 | \\ -O [mode] Choose what to optimize for |
| 404 | \\ Debug (default) Optimizations off, safety on | 404 | \\ Debug (default) Optimizations off, safety on |
| 405 | \\ ReleaseFast Optimizations on, safety off | 405 | \\ ReleaseFast Optimize for performance, safety off |
| 406 | \\ ReleaseSafe Optimizations on, safety on | 406 | \\ ReleaseSafe Optimize for performance, safety on |
| 407 | \\ ReleaseSmall Optimize for small binary, safety off | 407 | \\ ReleaseSmall Optimize for small binary, safety off |
| 408 | \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name | 408 | \\ --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), |
| 470 | 471 | ||
| 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 | } |
| 2699 | 2699 | ||
| 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); |
| 2702 | 2709 | ||
| ... | @@ -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; |
| 2716 | 2723 | ||
| 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 | } |
| 4178 | 4186 | ||
| 4187 | fn 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 matters | 4198 | /// 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. |
| 4181 | fn transQualTypeInitialized( | 4200 | fn 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 | } |
| 2384 | 2384 | ||
| 2385 | const 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 | |||
| 2385 | const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) { | 2391 | const 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 | } |
| 2396 | 2402 | ||
| 2403 | bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *self) { | ||
| 2404 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); | ||
| 2405 | return casted->hasArrayFiller(); | ||
| 2406 | } | ||
| 2407 | |||
| 2408 | bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *self) { | ||
| 2409 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); | ||
| 2410 | return casted->isStringLiteralInit(); | ||
| 2411 | } | ||
| 2412 | |||
| 2397 | const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) { | 2413 | const 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); |
| 1221 | ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *, | 1221 | ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *, |
| 1222 | struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *); | 1222 | struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *); |
| 1223 | ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self); | ||
| 1223 | 1224 | ||
| 1224 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned); | 1225 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned); |
| 1225 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *); | 1226 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *); |
| 1227 | ZIG_EXTERN_C bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *); | ||
| 1228 | ZIG_EXTERN_C bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *); | ||
| 1226 | ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *); | 1229 | ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *); |
| 1227 | ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self); | 1230 | ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self); |
| 1228 | 1231 |
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##rhs | 253 | #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) |
| 255 | 255 | ||
| 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__ >= 201112L | 256 | #if __STDC_VERSION__ >= 201112L |
| 348 | #define zig_noreturn _Noreturn | 257 | #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; |
| 502 | 411 | ||
| 503 | #endif | 412 | #endif |
| 504 | 413 | ||
| 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_MIN | 414 | #define zig_minInt_i8 INT8_MIN |
| 515 | #define zig_maxInt_i8 INT8_MAX | 415 | #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) |
| 536 | 436 | ||
| 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; |
| 1303 | 1203 | ||
| 1304 | #endif /* zig_has_int128 */ | 1204 | #endif /* zig_has_int128 */ |
| 1305 | 1205 | ||
| 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 | } |
| 1467 | 1364 | ||
| 1468 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { | 1365 | static 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 | } |
| 1471 | 1368 | ||
| 1472 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); | 1369 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); |
| 1473 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | 1370 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1474 | return __udivti3(lhs, rhs); | 1371 | return __udivti3(lhs, rhs); |
| 1475 | }; | 1372 | } |
| 1476 | 1373 | ||
| 1477 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); | 1374 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); |
| 1478 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | 1375 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1479 | return __divti3(lhs, rhs); | 1376 | return __divti3(lhs, rhs); |
| 1480 | }; | 1377 | } |
| 1481 | 1378 | ||
| 1482 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | 1379 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); |
| 1483 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { | 1380 | static 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_u128 | 1400 | #define zig_div_floor_u128 zig_div_trunc_u128 |
| 1504 | #define zig_mod_u128 zig_rem_u128 | 1401 | #define zig_mod_u128 zig_rem_u128 |
| 1505 | 1402 | ||
| 1506 | static 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 | |||
| 1510 | static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) { | 1403 | static 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 | } |
| 1539 | 1432 | ||
| 1540 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 1433 | static 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 | } |
| 1543 | 1436 | ||
| 1544 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 1437 | 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,7 +1439,7 @@ static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 1546 | } | 1439 | } |
| 1547 | 1440 | ||
| 1548 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 1441 | static 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 | } |
| 1551 | 1444 | ||
| 1552 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 1445 | 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,7 +1447,7 @@ static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 1554 | } | 1447 | } |
| 1555 | 1448 | ||
| 1556 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 1449 | static 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 | } |
| 1559 | 1452 | ||
| 1560 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { | 1453 | 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,7 +1455,7 @@ static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) { |
| 1562 | } | 1455 | } |
| 1563 | 1456 | ||
| 1564 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 1457 | static 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 | } |
| 1567 | 1460 | ||
| 1568 | #if zig_has_int128 | 1461 | #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 |
| 1697 | 1590 | ||
| 1698 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { | 1591 | static 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) { |
| 1711 | 1604 | ||
| 1712 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { | 1605 | static 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 | } |
| 1717 | 1610 | ||
| ... | @@ -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 | } |
| 1756 | 1649 | ||
| 1757 | static inline uint8_t zig_clz_i128(zig_i128 val, uint8_t bits) { | 1650 | static 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 | } |
| 1760 | 1653 | ||
| 1761 | static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) { | 1654 | 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,7 +1657,7 @@ static inline uint8_t zig_ctz_u128(zig_u128 val, uint8_t bits) { |
| 1764 | } | 1657 | } |
| 1765 | 1658 | ||
| 1766 | static inline uint8_t zig_ctz_i128(zig_i128 val, uint8_t bits) { | 1659 | static 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 | } |
| 1769 | 1662 | ||
| 1770 | static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) { | 1663 | 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,7 +1666,7 @@ static inline uint8_t zig_popcount_u128(zig_u128 val, uint8_t bits) { |
| 1773 | } | 1666 | } |
| 1774 | 1667 | ||
| 1775 | static inline uint8_t zig_popcount_i128(zig_i128 val, uint8_t bits) { | 1668 | static 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 | } |
| 1778 | 1671 | ||
| 1779 | static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) { | 1672 | 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,7 +1681,7 @@ static inline zig_u128 zig_byte_swap_u128(zig_u128 val, uint8_t bits) { |
| 1788 | } | 1681 | } |
| 1789 | 1682 | ||
| 1790 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, uint8_t bits) { | 1683 | static 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 | } |
| 1793 | 1686 | ||
| 1794 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) { | 1687 | 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,7 +1691,7 @@ static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, uint8_t bits) { |
| 1798 | } | 1691 | } |
| 1799 | 1692 | ||
| 1800 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { | 1693 | static 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 | } |
| 1803 | 1696 | ||
| 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 | } |
| 1974 | 1867 | ||
| 1868 | static 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 | |||
| 1947 | static 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 | |||
| 2026 | static 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 | |||
| 1975 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | 2105 | static 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 | #endif | 2957 | #endif |
| 2828 | 2958 | ||
| 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 1 | 2960 | #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 | #else | 2965 | #else |
| 2837 | #define zig_has_float_builtins 0 | 2966 | #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 | #endif | 2971 | #endif |
| 2844 | 2972 | ||
| 2845 | #define zig_has_f16 1 | 2973 | #define zig_has_f16 1 |
| 2846 | #define zig_bitSizeOf_f16 16 | ||
| 2847 | typedef uint16_t zig_repr_f16; | ||
| 2848 | #define zig_libc_name_f16(name) __##name##h | 2974 | #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 == 11 | 2976 | #if FLT_MANT_DIG == 11 |
| ... | @@ -2854,10 +2980,6 @@ typedef float zig_f16; | ... | @@ -2854,10 +2980,6 @@ typedef float zig_f16; |
| 2854 | typedef double zig_f16; | 2980 | typedef double zig_f16; |
| 2855 | #define zig_make_f16(fp, repr) fp | 2981 | #define zig_make_f16(fp, repr) fp |
| 2856 | #elif LDBL_MANT_DIG == 11 | 2982 | #elif LDBL_MANT_DIG == 11 |
| 2857 | #define zig_bitSizeOf_c_longdouble 16 | ||
| 2858 | #ifndef ZIG_TARGET_ABI_MSVC | ||
| 2859 | typedef zig_repr_f16 zig_repr_c_longdouble; | ||
| 2860 | #endif | ||
| 2861 | typedef long double zig_f16; | 2983 | typedef long double zig_f16; |
| 2862 | #define zig_make_f16(fp, repr) fp##l | 2984 | #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 | #else | 2991 | #else |
| 2870 | #undef zig_has_f16 | 2992 | #undef zig_has_f16 |
| 2871 | #define zig_has_f16 0 | 2993 | #define zig_has_f16 0 |
| 2872 | #define zig_bitSizeOf_repr_f16 16 | 2994 | #define zig_repr_f16 u16 |
| 2873 | typedef zig_repr_f16 zig_f16; | 2995 | typedef uint16_t zig_f16; |
| 2874 | #define zig_make_f16(fp, repr) repr | 2996 | #define zig_make_f16(fp, repr) repr |
| 2875 | #undef zig_make_special_f16 | 2997 | #undef zig_make_special_f16 |
| 2876 | #define zig_make_special_f16(sign, name, arg, repr) repr | 2998 | #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) repr | 3000 | #define zig_init_special_f16(sign, name, arg, repr) repr |
| 2879 | #endif | 3001 | #endif |
| 2880 | #if __APPLE__ && (defined(__i386__) || defined(__x86_64__)) | 3002 | #if __APPLE__ && (defined(__i386__) || defined(__x86_64__)) |
| 2881 | typedef zig_repr_f16 zig_compiler_rt_f16; | 3003 | typedef uint16_t zig_compiler_rt_f16; |
| 2882 | #else | 3004 | #else |
| 2883 | typedef zig_f16 zig_compiler_rt_f16; | 3005 | typedef zig_f16 zig_compiler_rt_f16; |
| 2884 | #endif | 3006 | #endif |
| 2885 | #define zig_compiler_rt_abbrev_zig_compiler_rt_f16 zig_compiler_rt_abbrev_zig_f16 | ||
| 2886 | 3007 | ||
| 2887 | #define zig_has_f32 1 | 3008 | #define zig_has_f32 1 |
| 2888 | #define zig_bitSizeOf_f32 32 | ||
| 2889 | typedef uint32_t zig_repr_f32; | ||
| 2890 | #define zig_libc_name_f32(name) name##f | 3009 | #define zig_libc_name_f32(name) name##f |
| 2891 | #if _MSC_VER | 3010 | #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; |
| 2900 | typedef double zig_f32; | 3019 | typedef double zig_f32; |
| 2901 | #define zig_make_f32(fp, repr) fp | 3020 | #define zig_make_f32(fp, repr) fp |
| 2902 | #elif LDBL_MANT_DIG == 24 | 3021 | #elif LDBL_MANT_DIG == 24 |
| 2903 | #define zig_bitSizeOf_c_longdouble 32 | ||
| 2904 | #ifndef ZIG_TARGET_ABI_MSVC | ||
| 2905 | typedef zig_repr_f32 zig_repr_c_longdouble; | ||
| 2906 | #endif | ||
| 2907 | typedef long double zig_f32; | 3022 | typedef long double zig_f32; |
| 2908 | #define zig_make_f32(fp, repr) fp##l | 3023 | #define zig_make_f32(fp, repr) fp##l |
| 2909 | #elif FLT32_MANT_DIG == 24 | 3024 | #elif FLT32_MANT_DIG == 24 |
| ... | @@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32; | ... | @@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32; |
| 2912 | #else | 3027 | #else |
| 2913 | #undef zig_has_f32 | 3028 | #undef zig_has_f32 |
| 2914 | #define zig_has_f32 0 | 3029 | #define zig_has_f32 0 |
| 2915 | #define zig_bitSizeOf_repr_f32 32 | 3030 | #define zig_repr_f32 u32 |
| 2916 | typedef zig_repr_f32 zig_f32; | 3031 | ypedef uint32_t zig_f32; |
| 2917 | #define zig_make_f32(fp, repr) repr | 3032 | #define zig_make_f32(fp, repr) repr |
| 2918 | #undef zig_make_special_f32 | 3033 | #undef zig_make_special_f32 |
| 2919 | #define zig_make_special_f32(sign, name, arg, repr) repr | 3034 | #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 | #endif | 3037 | #endif |
| 2923 | 3038 | ||
| 2924 | #define zig_has_f64 1 | 3039 | #define zig_has_f64 1 |
| 2925 | #define zig_bitSizeOf_f64 64 | ||
| 2926 | typedef uint64_t zig_repr_f64; | ||
| 2927 | #define zig_libc_name_f64(name) name | 3040 | #define zig_libc_name_f64(name) name |
| 2928 | #if _MSC_VER | 3041 | #if _MSC_VER |
| 2929 | #ifdef ZIG_TARGET_ABI_MSVC | ||
| 2930 | #define zig_bitSizeOf_c_longdouble 64 | ||
| 2931 | #ifndef ZIG_TARGET_ABI_MSVC | ||
| 2932 | typedef 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 == 53 | 3046 | #if FLT_MANT_DIG == 53 |
| 2940 | typedef float zig_f64; | 3047 | typedef float zig_f64; |
| 2941 | #define zig_make_f64(fp, repr) fp##f | 3048 | #define zig_make_f64(fp, repr) fp##f |
| ... | @@ -2943,10 +3050,6 @@ typedef float zig_f64; | ... | @@ -2943,10 +3050,6 @@ typedef float zig_f64; |
| 2943 | typedef double zig_f64; | 3050 | typedef double zig_f64; |
| 2944 | #define zig_make_f64(fp, repr) fp | 3051 | #define zig_make_f64(fp, repr) fp |
| 2945 | #elif LDBL_MANT_DIG == 53 | 3052 | #elif LDBL_MANT_DIG == 53 |
| 2946 | #define zig_bitSizeOf_c_longdouble 64 | ||
| 2947 | #ifndef ZIG_TARGET_ABI_MSVC | ||
| 2948 | typedef zig_repr_f64 zig_repr_c_longdouble; | ||
| 2949 | #endif | ||
| 2950 | typedef long double zig_f64; | 3053 | typedef long double zig_f64; |
| 2951 | #define zig_make_f64(fp, repr) fp##l | 3054 | #define zig_make_f64(fp, repr) fp##l |
| 2952 | #elif FLT64_MANT_DIG == 53 | 3055 | #elif FLT64_MANT_DIG == 53 |
| ... | @@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64; | ... | @@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64; |
| 2958 | #else | 3061 | #else |
| 2959 | #undef zig_has_f64 | 3062 | #undef zig_has_f64 |
| 2960 | #define zig_has_f64 0 | 3063 | #define zig_has_f64 0 |
| 2961 | #define zig_bitSizeOf_repr_f64 64 | 3064 | #define zig_repr_f64 u64 |
| 2962 | typedef zig_repr_f64 zig_f64; | 3065 | typedef uint64_t zig_f64; |
| 2963 | #define zig_make_f64(fp, repr) repr | 3066 | #define zig_make_f64(fp, repr) repr |
| 2964 | #undef zig_make_special_f64 | 3067 | #undef zig_make_special_f64 |
| 2965 | #define zig_make_special_f64(sign, name, arg, repr) repr | 3068 | #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 | #endif | 3071 | #endif |
| 2969 | 3072 | ||
| 2970 | #define zig_has_f80 1 | 3073 | #define zig_has_f80 1 |
| 2971 | #define zig_bitSizeOf_f80 80 | ||
| 2972 | typedef zig_u128 zig_repr_f80; | ||
| 2973 | #define zig_libc_name_f80(name) __##name##x | 3074 | #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 == 64 | 3076 | #if FLT_MANT_DIG == 64 |
| ... | @@ -2979,10 +3080,6 @@ typedef float zig_f80; | ... | @@ -2979,10 +3080,6 @@ typedef float zig_f80; |
| 2979 | typedef double zig_f80; | 3080 | typedef double zig_f80; |
| 2980 | #define zig_make_f80(fp, repr) fp | 3081 | #define zig_make_f80(fp, repr) fp |
| 2981 | #elif LDBL_MANT_DIG == 64 | 3082 | #elif LDBL_MANT_DIG == 64 |
| 2982 | #define zig_bitSizeOf_c_longdouble 80 | ||
| 2983 | #ifndef ZIG_TARGET_ABI_MSVC | ||
| 2984 | typedef zig_repr_f80 zig_repr_c_longdouble; | ||
| 2985 | #endif | ||
| 2986 | typedef long double zig_f80; | 3083 | typedef long double zig_f80; |
| 2987 | #define zig_make_f80(fp, repr) fp##l | 3084 | #define zig_make_f80(fp, repr) fp##l |
| 2988 | #elif FLT80_MANT_DIG == 64 | 3085 | #elif FLT80_MANT_DIG == 64 |
| ... | @@ -2997,8 +3094,8 @@ typedef __float80 zig_f80; | ... | @@ -2997,8 +3094,8 @@ typedef __float80 zig_f80; |
| 2997 | #else | 3094 | #else |
| 2998 | #undef zig_has_f80 | 3095 | #undef zig_has_f80 |
| 2999 | #define zig_has_f80 0 | 3096 | #define zig_has_f80 0 |
| 3000 | #define zig_bitSizeOf_repr_f80 128 | 3097 | #define zig_repr_f80 u128 |
| 3001 | typedef zig_repr_f80 zig_f80; | 3098 | typedef zig_u128 zig_f80; |
| 3002 | #define zig_make_f80(fp, repr) repr | 3099 | #define zig_make_f80(fp, repr) repr |
| 3003 | #undef zig_make_special_f80 | 3100 | #undef zig_make_special_f80 |
| 3004 | #define zig_make_special_f80(sign, name, arg, repr) repr | 3101 | #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 | #endif | 3104 | #endif |
| 3008 | 3105 | ||
| 3009 | #define zig_has_f128 1 | 3106 | #define zig_has_f128 1 |
| 3010 | #define zig_bitSizeOf_f128 128 | ||
| 3011 | typedef zig_u128 zig_repr_f128; | ||
| 3012 | #define zig_libc_name_f128(name) name##q | 3107 | #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 == 113 | 3109 | #if FLT_MANT_DIG == 113 |
| ... | @@ -3018,10 +3113,6 @@ typedef float zig_f128; | ... | @@ -3018,10 +3113,6 @@ typedef float zig_f128; |
| 3018 | typedef double zig_f128; | 3113 | typedef double zig_f128; |
| 3019 | #define zig_make_f128(fp, repr) fp | 3114 | #define zig_make_f128(fp, repr) fp |
| 3020 | #elif LDBL_MANT_DIG == 113 | 3115 | #elif LDBL_MANT_DIG == 113 |
| 3021 | #define zig_bitSizeOf_c_longdouble 128 | ||
| 3022 | #ifndef ZIG_TARGET_ABI_MSVC | ||
| 3023 | typedef zig_repr_f128 zig_repr_c_longdouble; | ||
| 3024 | #endif | ||
| 3025 | typedef long double zig_f128; | 3116 | typedef long double zig_f128; |
| 3026 | #define zig_make_f128(fp, repr) fp##l | 3117 | #define zig_make_f128(fp, repr) fp##l |
| 3027 | #elif FLT128_MANT_DIG == 113 | 3118 | #elif FLT128_MANT_DIG == 113 |
| ... | @@ -3038,50 +3129,49 @@ typedef __float128 zig_f128; | ... | @@ -3038,50 +3129,49 @@ typedef __float128 zig_f128; |
| 3038 | #else | 3129 | #else |
| 3039 | #undef zig_has_f128 | 3130 | #undef zig_has_f128 |
| 3040 | #define zig_has_f128 0 | 3131 | #define zig_has_f128 0 |
| 3041 | #define zig_bitSizeOf_repr_f128 128 | ||
| 3042 | typedef zig_repr_f128 zig_f128; | ||
| 3043 | #define zig_make_f128(fp, repr) repr | ||
| 3044 | #undef zig_make_special_f128 | 3132 | #undef zig_make_special_f128 |
| 3045 | #define zig_make_special_f128(sign, name, arg, repr) repr | ||
| 3046 | #undef zig_init_special_f128 | 3133 | #undef zig_init_special_f128 |
| 3134 | #if __APPLE__ || defined(__aarch64__) | ||
| 3135 | typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64; | ||
| 3136 | zig_basic_operator(zig_v2u64, xor_v2u64, ^) | ||
| 3137 | #define zig_repr_f128 v2u64 | ||
| 3138 | typedef 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 | ||
| 3146 | typedef 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) repr | 3149 | #define zig_init_special_f128(sign, name, arg, repr) repr |
| 3048 | #endif | 3150 | #endif |
| 3151 | #endif | ||
| 3049 | 3152 | ||
| 3050 | #ifdef zig_bitSizeOf_c_longdouble | 3153 | #if !_MSC_VER && defined(ZIG_TARGET_ABI_MSVC) |
| 3051 | 3154 | /* 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 | ||
| 3056 | typedef zig_f64 zig_c_longdouble; | 3155 | typedef zig_f64 zig_c_longdouble; |
| 3057 | typedef zig_repr_f64 zig_repr_c_longdouble; | 3156 | #elif _MSC_VER && !defined(ZIG_TARGET_ABI_MSVC) |
| 3157 | /* Emulate gnu abi on an msvc compiler */ | ||
| 3158 | typedef zig_f128 zig_c_longdouble; | ||
| 3058 | #else | 3159 | #else |
| 3160 | /* Target and compiler abi match */ | ||
| 3059 | typedef long double zig_c_longdouble; | 3161 | typedef long double zig_c_longdouble; |
| 3060 | #endif | 3162 | #endif |
| 3061 | 3163 | ||
| 3062 | #else /* zig_bitSizeOf_c_longdouble */ | 3164 | #define zig_bitCast_float(Type, ReprType) \ |
| 3063 | 3165 | static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \ | |
| 3064 | #define zig_has_c_longdouble 0 | ||
| 3065 | #define zig_bitSizeOf_repr_c_longdouble 128 | ||
| 3066 | typedef zig_f128 zig_c_longdouble; | ||
| 3067 | typedef 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 | } |
| 3078 | 3170 | zig_bitCast_float(f16, uint16_t) | |
| 3079 | zig_float_from_repr(f16) | 3171 | zig_bitCast_float(f32, uint32_t) |
| 3080 | zig_float_from_repr(f32) | 3172 | zig_bitCast_float(f64, uint64_t) |
| 3081 | zig_float_from_repr(f64) | 3173 | zig_bitCast_float(f80, zig_u128) |
| 3082 | zig_float_from_repr(f80) | 3174 | zig_bitCast_float(f128, zig_u128) |
| 3083 | zig_float_from_repr(f128) | ||
| 3084 | #endif | ||
| 3085 | 3175 | ||
| 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 | #endif | 3186 | #endif |
| 3097 | 3187 | ||
| 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); \ |
| 3101 | zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f32, 2) | 3191 | static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ |
| 3102 | zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f64, 2) | 3192 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ |
| 3103 | zig_convert_builtin(zig_f16, trunc, zig_f80, 2) | 3193 | ResType res; \ |
| 3104 | zig_convert_builtin(zig_f16, trunc, zig_f128, 2) | 3194 | ExternResType extern_res; \ |
| 3105 | zig_convert_builtin(zig_f32, extend, zig_compiler_rt_f16, 2) | 3195 | ExternArgType extern_arg; \ |
| 3106 | zig_convert_builtin(zig_f32, trunc, zig_f64, 2) | 3196 | memcpy(&extern_arg, &arg, sizeof(extern_arg)); \ |
| 3107 | zig_convert_builtin(zig_f32, trunc, zig_f80, 2) | 3197 | extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ |
| 3108 | zig_convert_builtin(zig_f32, trunc, zig_f128, 2) | 3198 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \ |
| 3109 | zig_convert_builtin(zig_f64, extend, zig_compiler_rt_f16, 2) | 3199 | memcpy(&res, &extern_res, sizeof(res)); \ |
| 3110 | zig_convert_builtin(zig_f64, extend, zig_f32, 2) | 3200 | return extern_res; \ |
| 3111 | zig_convert_builtin(zig_f64, trunc, zig_f80, 2) | 3201 | } |
| 3112 | zig_convert_builtin(zig_f64, trunc, zig_f128, 2) | 3202 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2) |
| 3113 | zig_convert_builtin(zig_f80, extend, zig_f16, 2) | 3203 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2) |
| 3114 | zig_convert_builtin(zig_f80, extend, zig_f32, 2) | 3204 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) |
| 3115 | zig_convert_builtin(zig_f80, extend, zig_f64, 2) | 3205 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) |
| 3116 | zig_convert_builtin(zig_f80, trunc, zig_f128, 2) | 3206 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) |
| 3117 | zig_convert_builtin(zig_f128, extend, zig_f16, 2) | 3207 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) |
| 3118 | zig_convert_builtin(zig_f128, extend, zig_f32, 2) | 3208 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) |
| 3119 | zig_convert_builtin(zig_f128, extend, zig_f64, 2) | 3209 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) |
| 3120 | zig_convert_builtin(zig_f128, extend, zig_f80, 2) | 3210 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) |
| 3121 | 3211 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2) | |
| 3122 | #define zig_float_negate_builtin_0(w) \ | 3212 | zig_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) { \ | 3213 | zig_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)( \ | 3214 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2) |
| 3125 | arg, \ | 3215 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2) |
| 3126 | zig_expand_concat(zig_shl_u, zig_bitSizeOf_repr_f##w)( \ | 3216 | zig_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), \ | 3217 | zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2) |
| 3128 | UINT8_C(w - 1) \ | 3218 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2) |
| 3129 | ) \ | 3219 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2) |
| 3130 | ); \ | 3220 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) |
| 3131 | } | 3221 | zig_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 | } |
| 3230 | zig_float_negate_builtin(16, , UINT16_C(1) << 15 ) | ||
| 3231 | zig_float_negate_builtin(32, , UINT32_C(1) << 31 ) | ||
| 3232 | zig_float_negate_builtin(64, , UINT64_C(1) << 63 ) | ||
| 3233 | zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0))) | ||
| 3234 | zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) | ||
| 3136 | 3235 | ||
| 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 | } |
| 3165 | 3264 | ||
| 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) |
| 3224 | zig_float_builtins(80) | 3322 | zig_float_builtins(80) |
| 3225 | zig_float_builtins(128) | 3323 | zig_float_builtins(128) |
| 3226 | 3324 | ||
| 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> | ||
| 3456 | typedef 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__) | ||
| 3479 | typedef 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) |
| 3228 | 3555 | ||
| 3229 | // TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 | 3556 | /* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */ |
| 3230 | 3557 | ||
| 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) |
| 3316 | zig_msvc_atomics(i64, int64_t, __int64, 64) | 3643 | zig_msvc_atomics(i64, int64_t, __int64, 64) |
| 3317 | #endif | 3644 | #endif |
| 3318 | 3645 | ||
| 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 | |||
| 3364 | zig_msvc_flt_atomics(f32, long, ) | 3670 | zig_msvc_flt_atomics(f32, long, ) |
| 3365 | #if _M_X64 | 3671 | #if _M_X64 |
| 3366 | zig_msvc_flt_atomics(f64, int64_t, 64) | 3672 | zig_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 |
| 3421 | static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) { | 3727 | static 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 | |||
| 3436 | zig_msvc_atomics_128xchg(u128) | ||
| 3437 | zig_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 | |||
| 3452 | zig_msvc_atomics_128op(u128, add) | ||
| 3453 | zig_msvc_atomics_128op(u128, sub) | ||
| 3454 | zig_msvc_atomics_128op(u128, or) | ||
| 3455 | zig_msvc_atomics_128op(u128, xor) | ||
| 3456 | zig_msvc_atomics_128op(u128, and) | ||
| 3457 | zig_msvc_atomics_128op(u128, nand) | ||
| 3458 | zig_msvc_atomics_128op(u128, min) | ||
| 3459 | zig_msvc_atomics_128op(u128, max) | ||
| 3460 | #endif /* _M_IX86 */ | 3730 | #endif /* _M_IX86 */ |
| 3461 | 3731 | ||
| 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 | } |
| 402 | 402 | ||
| 403 | test "explicit cast from integer to error type" { | 403 | test "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; // TODO | 405 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 407 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 406 | 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 | |||
| 1653 | test "@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 | } |
| 457 | 457 | ||
| 458 | test "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 | |||
| 458 | test "using @ptrCast on function pointers" { | 475 | test "using @ptrCast on function pointers" { |
| 459 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 476 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 460 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 477 | 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 | } |
| 487 | 487 | ||
| 488 | test "Type.Fn" { | 488 | test "Type.Fn" { |
| 489 | if (true) { | 489 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 490 | // https://github.com/ziglang/zig/issues/12360 | 490 | 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 | } | ||
| 493 | 492 | ||
| 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 field | 30 | // :9:1: error: union initializer must initialize one field |
| 31 | // :1:12: note: union declared here | 31 | // :1:12: note: union declared here |
| 32 | // :14:20: error: cannot initialize multiple union fields at once, unions can only have one active field | 32 | // :14:20: error: cannot initialize multiple union fields at once; unions can only have one active field |
| 33 | // :14:31: note: additional initializer here | 33 | // :14:31: note: additional initializer here |
| 34 | // :1:12: note: union declared here | 34 | // :1:12: note: union declared here |
| 35 | // :18:21: error: union initializer must initialize one field | 35 | // :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 field | 36 | // :22:20: error: cannot initialize multiple union fields at once; unions can only have one active field |
| 37 | // :22:31: note: additional initializer here | 37 | // :22:31: note: additional initializer here |
| 38 | // :5:12: note: union declared here | 38 | // :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=stage2 | 21 | // backend=stage2 |
| 22 | // target=native | 22 | // target=native |
| 23 | // | 23 | // |
| 24 | // :4:33: error: integer and float literals passed variadic function must be casted to a fixed-size number type | 24 | // :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 function | 25 | // :9:24: error: arrays must be passed by reference to variadic function |
| 26 | // :13:24: error: cannot pass 'u48' to variadic function | 26 | // :13:24: error: cannot pass 'u48' to variadic function |
| 27 | // :13:24: note: only integers with power of two bits are extern compatible | 27 | // :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 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub 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 | |||
| 11 | fn getNullPtr() ?*const anyopaque { | ||
| 12 | return null; | ||
| 13 | } | ||
| 14 | pub 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.h | 1041 | 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 | } |