| 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 | 1422 | |
| 1423 | 1423 | {#header_open|Thread Local Variables#} |
| 1424 | 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 | 1427 | {#code_begin|test|test_thread_local_variables#} |
| 1427 | 1428 | const std = @import("std"); |
| 1428 | 1429 | const assert = std.debug.assert; |
| ... | ... | @@ -4278,7 +4279,7 @@ const expectError = std.testing.expectError; |
| 4278 | 4279 | fn isFieldOptional(comptime T: type, field_index: usize) !bool { |
| 4279 | 4280 | const fields = @typeInfo(T).Struct.fields; |
| 4280 | 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 | 4283 | // unique comptime-known value each time. |
| 4283 | 4284 | inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .Optional, |
| 4284 | 4285 | else => return error.IndexOutOfBounds, |
| ... | ... | @@ -4667,6 +4668,29 @@ test "for basics" { |
| 4667 | 4668 | sum2 += @intCast(i32, i); |
| 4668 | 4669 | } |
| 4669 | 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 | 4696 | test "for reference" { |
| ... | ... | @@ -4710,8 +4734,8 @@ const expect = std.testing.expect; |
| 4710 | 4734 | |
| 4711 | 4735 | test "nested break" { |
| 4712 | 4736 | var count: usize = 0; |
| 4713 | outer: for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { | |
| 4714 | for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { | |
| 4737 | outer: for (1..6) |_| { | |
| 4738 | for (1..6) |_| { | |
| 4715 | 4739 | count += 1; |
| 4716 | 4740 | break :outer; |
| 4717 | 4741 | } |
| ... | ... | @@ -4721,8 +4745,8 @@ test "nested break" { |
| 4721 | 4745 | |
| 4722 | 4746 | test "nested continue" { |
| 4723 | 4747 | var count: usize = 0; |
| 4724 | outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| { | |
| 4725 | for ([_]i32{ 1, 2, 3, 4, 5 }) |_| { | |
| 4748 | outer: for (1..9) |_| { | |
| 4749 | for (1..6) |_| { | |
| 4726 | 4750 | count += 1; |
| 4727 | 4751 | continue :outer; |
| 4728 | 4752 | } |
| ... | ... | @@ -8017,7 +8041,7 @@ pub const CallModifier = enum { |
| 8017 | 8041 | <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p> |
| 8018 | 8042 | <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p> |
| 8019 | 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 | 8045 | </p> |
| 8022 | 8046 | <p> |
| 8023 | 8047 | If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer, |
| ... | ... | @@ -8167,7 +8191,7 @@ test "main" { |
| 8167 | 8191 | <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p> |
| 8168 | 8192 | <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p> |
| 8169 | 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 | 8195 | </p> |
| 8172 | 8196 | <p> |
| 8173 | 8197 | If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer, |
| ... | ... | @@ -8553,16 +8577,27 @@ test "@hasDecl" { |
| 8553 | 8577 | </p> |
| 8554 | 8578 | <ul> |
| 8555 | 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 | 8581 | The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference. |
| 8558 | 8582 | </li> |
| 8559 | <li>{#syntax#}@import("root"){#endsyntax#} - Points to the root source file. | |
| 8560 | This is usually <code>src/main.zig</code> but it depends on what file is chosen to be built. | |
| 8583 | <li>{#syntax#}@import("root"){#endsyntax#} - Root source file | |
| 8584 | This is usually <code>src/main.zig</code> but depends on what file is built. | |
| 8561 | 8585 | </li> |
| 8562 | 8586 | </ul> |
| 8563 | 8587 | {#see_also|Compile Variables|@embedFile#} |
| 8564 | 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 | 8601 | {#header_open|@intCast#} |
| 8567 | 8602 | <pre>{#syntax#}@intCast(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre> |
| 8568 | 8603 | <p> |
| ... | ... | @@ -8780,7 +8815,9 @@ test "@wasmMemoryGrow" { |
| 8780 | 8815 | <pre>{#syntax#}@popCount(operand: anytype) anytype{#endsyntax#}</pre> |
| 8781 | 8816 | <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type.</p> |
| 8782 | 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 | 8821 | <p> |
| 8785 | 8822 | If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer, |
| 8786 | 8823 | the return type is {#syntax#}comptime_int{#endsyntax#}. |
| ... | ... | @@ -8812,6 +8849,8 @@ test "@wasmMemoryGrow" { |
| 8812 | 8849 | pub const PrefetchOptions = struct { |
| 8813 | 8850 | /// Whether the prefetch should prepare for a read or a write. |
| 8814 | 8851 | rw: Rw = .read, |
| 8852 | /// The data's locality in an inclusive range from 0 to 3. | |
| 8853 | /// | |
| 8815 | 8854 | /// 0 means no temporal locality. That is, the data can be immediately |
| 8816 | 8855 | /// dropped from the cache after it is accessed. |
| 8817 | 8856 | /// |
| ... | ... | @@ -8821,12 +8860,12 @@ pub const PrefetchOptions = struct { |
| 8821 | 8860 | /// The cache that the prefetch should be preformed on. |
| 8822 | 8861 | cache: Cache = .data, |
| 8823 | 8862 | |
| 8824 | pub const Rw = enum { | |
| 8863 | pub const Rw = enum(u1) { | |
| 8825 | 8864 | read, |
| 8826 | 8865 | write, |
| 8827 | 8866 | }; |
| 8828 | 8867 | |
| 8829 | pub const Cache = enum { | |
| 8868 | pub const Cache = enum(u1) { | |
| 8830 | 8869 | instruction, |
| 8831 | 8870 | data, |
| 8832 | 8871 | }; |
| ... | ... | @@ -10948,7 +10987,7 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke |
| 10948 | 10987 | </p> |
| 10949 | 10988 | <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p> |
| 10950 | 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 | 10991 | <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}. |
| 10953 | 10992 | When a C pointer is coerced to a non-optional pointer, safety-checked |
| 10954 | 10993 | {#link|Undefined Behavior#} occurs if the address is 0. |
| ... | ... | @@ -11966,6 +12005,17 @@ fn readU32Be() u32 {} |
| 11966 | 12005 | </ul> |
| 11967 | 12006 | </td> |
| 11968 | 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 | 12019 | <tr> |
| 11970 | 12020 | <th scope="row"> |
| 11971 | 12021 | <pre>{#syntax#}nosuspend{#endsyntax#}</pre> |
lib/std/Build/Cache.zig+1-1| ... | ... | @@ -184,7 +184,7 @@ pub const File = struct { |
| 184 | 184 | pub const HashHelper = struct { |
| 185 | 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 | 188 | pub fn addBytes(hh: *HashHelper, bytes: []const u8) void { |
| 189 | 189 | hh.hasher.update(mem.asBytes(&bytes.len)); |
| 190 | 190 | hh.hasher.update(bytes); |
lib/std/RingBuffer.zig+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //! This ring buffer stores read and write indices while being able to utilise |
| 2 | 2 | //! the full backing slice by incrementing the indices modulo twice the slice's |
| 3 | 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 | 5 | //! looking at the difference between the read and write indices without adding |
| 6 | 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 | //! 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 | 2 | //! Does not do perfect grammar and character class checking, but should be robust against URIs in the wild. |
| 3 | 3 | |
| 4 | 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 | 221 | /// Asserts the array has at least one item. |
| 222 | 222 | /// Invalidates pointers to end of list. |
| 223 | 223 | /// This operation is O(N). |
| 224 | /// This preserves item order. Use `swapRemove` if order preservation is not important. | |
| 224 | 225 | pub fn orderedRemove(self: *Self, i: usize) T { |
| 225 | 226 | const newlen = self.items.len - 1; |
| 226 | 227 | if (newlen == i) return self.pop(); |
| ... | ... | @@ -235,6 +236,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 235 | 236 | /// Removes the element at the specified index and returns it. |
| 236 | 237 | /// The empty slot is filled from the end of the list. |
| 237 | 238 | /// This operation is O(1). |
| 239 | /// This may not preserve item order. Use `orderedRemove` if you need to preserve order. | |
| 238 | 240 | pub fn swapRemove(self: *Self, i: usize) T { |
| 239 | 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 | 35 | const Allocator = std.mem.Allocator; |
| 36 | 36 | |
| 37 | 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 | 41 | /// can be copied by value, and does not require deinitialization. |
| 40 | /// Both possible implementations fulfill the same interface. | |
| 41 | 42 | pub fn StaticBitSet(comptime size: usize) type { |
| 42 | 43 | if (size <= @bitSizeOf(usize)) { |
| 43 | 44 | return IntegerBitSet(size); |
lib/std/builtin.zig+27| ... | ... | @@ -144,22 +144,47 @@ pub const Mode = OptimizeMode; |
| 144 | 144 | /// This data structure is used by the Zig language code generation and |
| 145 | 145 | /// therefore must be kept in sync with the compiler implementation. |
| 146 | 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 | 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 | 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 | 157 | Naked, |
| 158 | /// Functions with this calling convention are called asynchronously, | |
| 159 | /// as if called as `async function()`. | |
| 150 | 160 | Async, |
| 161 | /// Functions with this calling convention are inlined at all call sites. | |
| 151 | 162 | Inline, |
| 163 | /// x86-only. | |
| 152 | 164 | Interrupt, |
| 153 | 165 | Signal, |
| 166 | /// x86-only. | |
| 154 | 167 | Stdcall, |
| 168 | /// x86-only. | |
| 155 | 169 | Fastcall, |
| 170 | /// x86-only. | |
| 156 | 171 | Vectorcall, |
| 172 | /// x86-only. | |
| 157 | 173 | Thiscall, |
| 174 | /// ARM Procedure Call Standard (obsolete) | |
| 175 | /// ARM-only. | |
| 158 | 176 | APCS, |
| 177 | /// ARM Architecture Procedure Call Standard (current standard) | |
| 178 | /// ARM-only. | |
| 159 | 179 | AAPCS, |
| 180 | /// ARM Architecture Procedure Call Standard Vector Floating-Point | |
| 181 | /// ARM-only. | |
| 160 | 182 | AAPCSVFP, |
| 183 | /// x86-64-only. | |
| 161 | 184 | SysV, |
| 185 | /// x86-64-only. | |
| 162 | 186 | Win64, |
| 187 | /// AMD GPU, NVPTX, or SPIR-V kernel | |
| 163 | 188 | Kernel, |
| 164 | 189 | }; |
| 165 | 190 | |
| ... | ... | @@ -716,6 +741,8 @@ pub const VaList = switch (builtin.cpu.arch) { |
| 716 | 741 | pub const PrefetchOptions = struct { |
| 717 | 742 | /// Whether the prefetch should prepare for a read or a write. |
| 718 | 743 | rw: Rw = .read, |
| 744 | /// The data's locality in an inclusive range from 0 to 3. | |
| 745 | /// | |
| 719 | 746 | /// 0 means no temporal locality. That is, the data can be immediately |
| 720 | 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 | 3846 | pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void; |
| 3847 | 3847 | pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t; |
| 3848 | 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 | 1143 | pub const HUP = 0x0010; |
| 1144 | 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 | 29 | extern "c" fn __error() *c_int; |
| 30 | 30 | pub const _errno = __error; |
| 31 | 31 | |
| 32 | pub extern "c" var malloc_options: [*:0]const u8; | |
| 33 | ||
| 32 | 34 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; |
| 33 | 35 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
| 34 | 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 | 44 | |
| 43 | 45 | pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; |
| 44 | 46 | pub extern "c" fn malloc_usable_size(?*const anyopaque) usize; |
| 47 | pub extern "c" fn reallocf(?*anyopaque, usize) ?*anyopaque; | |
| 45 | 48 | |
| 46 | 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 | 53 | |
| 51 | 54 | pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int; |
| 52 | 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 | 60 | pub const sf_hdtr = extern struct { |
| 55 | 61 | headers: [*]const iovec_const, |
| ... | ... | @@ -1102,6 +1108,11 @@ pub const DT = struct { |
| 1102 | 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 | 1116 | /// add event to kq (implies enable) |
| 1106 | 1117 | pub const EV_ADD = 0x0001; |
| 1107 | 1118 | |
| ... | ... | @@ -1383,15 +1394,47 @@ pub const mcontext_t = switch (builtin.cpu.arch) { |
| 1383 | 1394 | rflags: u64, |
| 1384 | 1395 | rsp: u64, |
| 1385 | 1396 | ss: u64, |
| 1386 | len: u64, | |
| 1387 | fpformat: u64, | |
| 1388 | ownedfp: u64, | |
| 1389 | fpstate: [64]u64 align(16), | |
| 1397 | len: c_long, | |
| 1398 | fpformat: c_long, | |
| 1399 | ownedfp: c_long, | |
| 1400 | fpstate: [64]c_long align(16), | |
| 1390 | 1401 | fsbase: u64, |
| 1391 | 1402 | gsbase: u64, |
| 1392 | 1403 | xfpustate: u64, |
| 1393 | 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 | 1439 | .aarch64 => extern struct { |
| 1397 | 1440 | gpregs: extern struct { |
| ... | ... | @@ -2205,3 +2248,46 @@ pub const shm_largeconf = extern struct { |
| 2205 | 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 | 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 | 5 | const iovec = std.os.iovec; |
| 6 | 6 | const iovec_const = std.os.iovec_const; |
| 7 | 7 | |
| 8 | const status_t = i32; | |
| 9 | ||
| 8 | 10 | extern "c" fn _errnop() *c_int; |
| 9 | 11 | |
| 10 | 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 | 18 | pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32; |
| 15 | 19 | |
| ... | ... | @@ -1038,3 +1042,22 @@ pub const termios = extern struct { |
| 1038 | 1042 | }; |
| 1039 | 1043 | |
| 1040 | 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 | 1633 | pub const HUP = 0x0010; |
| 1634 | 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 | 1927 | pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 { |
| 1928 | 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 | 10 | |
| 11 | 11 | pub const DecompressStreamOptions = struct { |
| 12 | 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 | 16 | pub fn DecompressStream( |
lib/std/compress/zstandard/decode/fse.zig+1-1| ... | ... | @@ -21,7 +21,7 @@ pub fn decodeFseTable( |
| 21 | 21 | var accumulated_probability: u16 = 0; |
| 22 | 22 | |
| 23 | 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 | 25 | // but power of two (remaining probabilities + 1) need max bits set to 1 more. |
| 26 | 26 | const max_bits = std.math.log2_int(u16, total_probability - accumulated_probability + 1) + 1; |
| 27 | 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 | 71 | |
| 72 | 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 | 74 | /// SHA-224 |
| 81 | 75 | pub const Sha224 = Sha2x32(Sha224Params); |
| 82 | 76 | |
| ... | ... | @@ -203,7 +197,7 @@ fn Sha2x32(comptime params: Sha2Params32) type { |
| 203 | 197 | s[i] = mem.readIntBig(u32, mem.asBytes(elem)); |
| 204 | 198 | } |
| 205 | 199 | |
| 206 | if (!isComptime()) { | |
| 200 | if (!@inComptime()) { | |
| 207 | 201 | switch (builtin.cpu.arch) { |
| 208 | 202 | .aarch64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) { |
| 209 | 203 | var x: v4u32 = d.s[0..4].*; |
lib/std/debug.zig+2| ... | ... | @@ -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 | 656 | pub const TTY = struct { |
| 655 | 657 | pub const Color = enum { |
| 656 | 658 | Red, |
lib/std/elf.zig+88-5| ... | ... | @@ -221,75 +221,138 @@ pub const DT_IA_64_NUM = 1; |
| 221 | 221 | |
| 222 | 222 | pub const DT_NIOS2_GP = 0x70000002; |
| 223 | 223 | |
| 224 | /// Program header table entry unused | |
| 224 | 225 | pub const PT_NULL = 0; |
| 226 | /// Loadable program segment | |
| 225 | 227 | pub const PT_LOAD = 1; |
| 228 | /// Dynamic linking information | |
| 226 | 229 | pub const PT_DYNAMIC = 2; |
| 230 | /// Program interpreter | |
| 227 | 231 | pub const PT_INTERP = 3; |
| 232 | /// Auxiliary information | |
| 228 | 233 | pub const PT_NOTE = 4; |
| 234 | /// Reserved | |
| 229 | 235 | pub const PT_SHLIB = 5; |
| 236 | /// Entry for header table itself | |
| 230 | 237 | pub const PT_PHDR = 6; |
| 238 | /// Thread-local storage segment | |
| 231 | 239 | pub const PT_TLS = 7; |
| 240 | /// Number of defined types | |
| 232 | 241 | pub const PT_NUM = 8; |
| 242 | /// Start of OS-specific | |
| 233 | 243 | pub const PT_LOOS = 0x60000000; |
| 244 | /// GCC .eh_frame_hdr segment | |
| 234 | 245 | pub const PT_GNU_EH_FRAME = 0x6474e550; |
| 246 | /// Indicates stack executability | |
| 235 | 247 | pub const PT_GNU_STACK = 0x6474e551; |
| 248 | /// Read-only after relocation | |
| 236 | 249 | pub const PT_GNU_RELRO = 0x6474e552; |
| 237 | 250 | pub const PT_LOSUNW = 0x6ffffffa; |
| 251 | /// Sun specific segment | |
| 238 | 252 | pub const PT_SUNWBSS = 0x6ffffffa; |
| 253 | /// Stack segment | |
| 239 | 254 | pub const PT_SUNWSTACK = 0x6ffffffb; |
| 240 | 255 | pub const PT_HISUNW = 0x6fffffff; |
| 256 | /// End of OS-specific | |
| 241 | 257 | pub const PT_HIOS = 0x6fffffff; |
| 258 | /// Start of processor-specific | |
| 242 | 259 | pub const PT_LOPROC = 0x70000000; |
| 260 | /// End of processor-specific | |
| 243 | 261 | pub const PT_HIPROC = 0x7fffffff; |
| 244 | 262 | |
| 263 | /// Section header table entry unused | |
| 245 | 264 | pub const SHT_NULL = 0; |
| 265 | /// Program data | |
| 246 | 266 | pub const SHT_PROGBITS = 1; |
| 267 | /// Symbol table | |
| 247 | 268 | pub const SHT_SYMTAB = 2; |
| 269 | /// String table | |
| 248 | 270 | pub const SHT_STRTAB = 3; |
| 271 | /// Relocation entries with addends | |
| 249 | 272 | pub const SHT_RELA = 4; |
| 273 | /// Symbol hash table | |
| 250 | 274 | pub const SHT_HASH = 5; |
| 275 | /// Dynamic linking information | |
| 251 | 276 | pub const SHT_DYNAMIC = 6; |
| 277 | /// Notes | |
| 252 | 278 | pub const SHT_NOTE = 7; |
| 279 | /// Program space with no data (bss) | |
| 253 | 280 | pub const SHT_NOBITS = 8; |
| 281 | /// Relocation entries, no addends | |
| 254 | 282 | pub const SHT_REL = 9; |
| 283 | /// Reserved | |
| 255 | 284 | pub const SHT_SHLIB = 10; |
| 285 | /// Dynamic linker symbol table | |
| 256 | 286 | pub const SHT_DYNSYM = 11; |
| 287 | /// Array of constructors | |
| 257 | 288 | pub const SHT_INIT_ARRAY = 14; |
| 289 | /// Array of destructors | |
| 258 | 290 | pub const SHT_FINI_ARRAY = 15; |
| 291 | /// Array of pre-constructors | |
| 259 | 292 | pub const SHT_PREINIT_ARRAY = 16; |
| 293 | /// Section group | |
| 260 | 294 | pub const SHT_GROUP = 17; |
| 295 | /// Extended section indices | |
| 261 | 296 | pub const SHT_SYMTAB_SHNDX = 18; |
| 297 | /// Start of OS-specific | |
| 262 | 298 | pub const SHT_LOOS = 0x60000000; |
| 299 | /// End of OS-specific | |
| 263 | 300 | pub const SHT_HIOS = 0x6fffffff; |
| 301 | /// Start of processor-specific | |
| 264 | 302 | pub const SHT_LOPROC = 0x70000000; |
| 303 | /// End of processor-specific | |
| 265 | 304 | pub const SHT_HIPROC = 0x7fffffff; |
| 305 | /// Start of application-specific | |
| 266 | 306 | pub const SHT_LOUSER = 0x80000000; |
| 307 | /// End of application-specific | |
| 267 | 308 | pub const SHT_HIUSER = 0xffffffff; |
| 268 | 309 | |
| 310 | /// Local symbol | |
| 269 | 311 | pub const STB_LOCAL = 0; |
| 312 | /// Global symbol | |
| 270 | 313 | pub const STB_GLOBAL = 1; |
| 314 | /// Weak symbol | |
| 271 | 315 | pub const STB_WEAK = 2; |
| 316 | /// Number of defined types | |
| 272 | 317 | pub const STB_NUM = 3; |
| 318 | /// Start of OS-specific | |
| 273 | 319 | pub const STB_LOOS = 10; |
| 320 | /// Unique symbol | |
| 274 | 321 | pub const STB_GNU_UNIQUE = 10; |
| 322 | /// End of OS-specific | |
| 275 | 323 | pub const STB_HIOS = 12; |
| 324 | /// Start of processor-specific | |
| 276 | 325 | pub const STB_LOPROC = 13; |
| 326 | /// End of processor-specific | |
| 277 | 327 | pub const STB_HIPROC = 15; |
| 278 | 328 | |
| 279 | 329 | pub const STB_MIPS_SPLIT_COMMON = 13; |
| 280 | 330 | |
| 331 | /// Symbol type is unspecified | |
| 281 | 332 | pub const STT_NOTYPE = 0; |
| 333 | /// Symbol is a data object | |
| 282 | 334 | pub const STT_OBJECT = 1; |
| 335 | /// Symbol is a code object | |
| 283 | 336 | pub const STT_FUNC = 2; |
| 337 | /// Symbol associated with a section | |
| 284 | 338 | pub const STT_SECTION = 3; |
| 339 | /// Symbol's name is file name | |
| 285 | 340 | pub const STT_FILE = 4; |
| 341 | /// Symbol is a common data object | |
| 286 | 342 | pub const STT_COMMON = 5; |
| 343 | /// Symbol is thread-local data object | |
| 287 | 344 | pub const STT_TLS = 6; |
| 345 | /// Number of defined types | |
| 288 | 346 | pub const STT_NUM = 7; |
| 347 | /// Start of OS-specific | |
| 289 | 348 | pub const STT_LOOS = 10; |
| 349 | /// Symbol is indirect code object | |
| 290 | 350 | pub const STT_GNU_IFUNC = 10; |
| 351 | /// End of OS-specific | |
| 291 | 352 | pub const STT_HIOS = 12; |
| 353 | /// Start of processor-specific | |
| 292 | 354 | pub const STT_LOPROC = 13; |
| 355 | /// End of processor-specific | |
| 293 | 356 | pub const STT_HIPROC = 15; |
| 294 | 357 | |
| 295 | 358 | pub const STT_SPARC_REGISTER = 13; |
| ... | ... | @@ -656,6 +719,13 @@ pub const Elf32_Sym = extern struct { |
| 656 | 719 | st_info: u8, |
| 657 | 720 | st_other: u8, |
| 658 | 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 | 730 | pub const Elf64_Sym = extern struct { |
| 661 | 731 | st_name: Elf64_Word, |
| ... | ... | @@ -664,6 +734,13 @@ pub const Elf64_Sym = extern struct { |
| 664 | 734 | st_shndx: Elf64_Section, |
| 665 | 735 | st_value: Elf64_Addr, |
| 666 | 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 | 745 | pub const Elf32_Syminfo = extern struct { |
| 669 | 746 | si_boundto: Elf32_Half, |
| ... | ... | @@ -681,7 +758,7 @@ pub const Elf32_Rel = extern struct { |
| 681 | 758 | return @truncate(u24, self.r_info >> 8); |
| 682 | 759 | } |
| 683 | 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 | 764 | pub const Elf64_Rel = extern struct { |
| ... | ... | @@ -692,7 +769,7 @@ pub const Elf64_Rel = extern struct { |
| 692 | 769 | return @truncate(u32, self.r_info >> 32); |
| 693 | 770 | } |
| 694 | 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 | 775 | pub const Elf32_Rela = extern struct { |
| ... | ... | @@ -704,7 +781,7 @@ pub const Elf32_Rela = extern struct { |
| 704 | 781 | return @truncate(u24, self.r_info >> 8); |
| 705 | 782 | } |
| 706 | 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 | 787 | pub const Elf64_Rela = extern struct { |
| ... | ... | @@ -716,7 +793,7 @@ pub const Elf64_Rela = extern struct { |
| 716 | 793 | return @truncate(u32, self.r_info >> 32); |
| 717 | 794 | } |
| 718 | 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 | 799 | pub const Elf32_Dyn = extern struct { |
| ... | ... | @@ -1630,14 +1707,20 @@ pub const PF_MASKOS = 0x0ff00000; |
| 1630 | 1707 | /// Bits for processor-specific semantics. |
| 1631 | 1708 | pub const PF_MASKPROC = 0xf0000000; |
| 1632 | 1709 | |
| 1633 | // Special section indexes used in Elf{32,64}_Sym. | |
| 1710 | /// Undefined section | |
| 1634 | 1711 | pub const SHN_UNDEF = 0; |
| 1712 | /// Start of reserved indices | |
| 1635 | 1713 | pub const SHN_LORESERVE = 0xff00; |
| 1714 | /// Start of processor-specific | |
| 1636 | 1715 | pub const SHN_LOPROC = 0xff00; |
| 1716 | /// End of processor-specific | |
| 1637 | 1717 | pub const SHN_HIPROC = 0xff1f; |
| 1638 | 1718 | pub const SHN_LIVEPATCH = 0xff20; |
| 1719 | /// Associated symbol is absolute | |
| 1639 | 1720 | pub const SHN_ABS = 0xfff1; |
| 1721 | /// Associated symbol is common | |
| 1640 | 1722 | pub const SHN_COMMON = 0xfff2; |
| 1723 | /// End of reserved indices | |
| 1641 | 1724 | pub const SHN_HIRESERVE = 0xffff; |
| 1642 | 1725 | |
| 1643 | 1726 | /// AMD x86-64 relocations. |
lib/std/fmt.zig+2-9| ... | ... | @@ -41,7 +41,7 @@ pub const FormatOptions = struct { |
| 41 | 41 | /// brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...} |
| 42 | 42 | /// - *specifier* is a type-dependent formatting option that determines how a type should formatted (see below) |
| 43 | 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 | 45 | /// - *width* is the total width of the field in characters |
| 46 | 46 | /// - *precision* specifies how many decimals a formatted number should have |
| 47 | 47 | /// |
| ... | ... | @@ -1428,8 +1428,7 @@ pub fn formatInt( |
| 1428 | 1428 | var a: MinInt = abs_value; |
| 1429 | 1429 | var index: usize = buf.len; |
| 1430 | 1430 | |
| 1431 | // TODO isComptime here because of https://github.com/ziglang/zig/issues/13335. | |
| 1432 | if (base == 10 and !isComptime()) { | |
| 1431 | if (base == 10) { | |
| 1433 | 1432 | while (a >= 100) : (a = @divTrunc(a, 100)) { |
| 1434 | 1433 | index -= 2; |
| 1435 | 1434 | buf[index..][0..2].* = digits2(@intCast(usize, a % 100)); |
| ... | ... | @@ -1469,12 +1468,6 @@ pub fn formatInt( |
| 1469 | 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 | 1471 | pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) usize { |
| 1479 | 1472 | var fbs = std.io.fixedBufferStream(out_buf); |
| 1480 | 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 | 1236 | .capable_io_mode = std.io.default_mode, |
| 1237 | 1237 | .intended_io_mode = flags.intended_io_mode, |
| 1238 | 1238 | }; |
| 1239 | errdefer file.close(); | |
| 1239 | 1240 | var io: w.IO_STATUS_BLOCK = undefined; |
| 1240 | 1241 | const range_off: w.LARGE_INTEGER = 0; |
| 1241 | 1242 | const range_len: w.LARGE_INTEGER = 1; |
| ... | ... | @@ -1396,6 +1397,7 @@ pub const Dir = struct { |
| 1396 | 1397 | .capable_io_mode = std.io.default_mode, |
| 1397 | 1398 | .intended_io_mode = flags.intended_io_mode, |
| 1398 | 1399 | }; |
| 1400 | errdefer file.close(); | |
| 1399 | 1401 | var io: w.IO_STATUS_BLOCK = undefined; |
| 1400 | 1402 | const range_off: w.LARGE_INTEGER = 0; |
| 1401 | 1403 | const range_len: w.LARGE_INTEGER = 1; |
| ... | ... | @@ -2210,7 +2212,7 @@ pub const Dir = struct { |
| 2210 | 2212 | var need_to_retry: bool = false; |
| 2211 | 2213 | parent_dir.deleteDir(name) catch |err| switch (err) { |
| 2212 | 2214 | error.FileNotFound => {}, |
| 2213 | error.DirNotEmpty => need_to_retry = false, | |
| 2215 | error.DirNotEmpty => need_to_retry = true, | |
| 2214 | 2216 | else => |e| return e, |
| 2215 | 2217 | }; |
| 2216 | 2218 | |
| ... | ... | @@ -2913,6 +2915,7 @@ pub const OpenSelfExeError = error{ |
| 2913 | 2915 | /// On Windows, file paths cannot contain these characters: |
| 2914 | 2916 | /// '/', '*', '?', '"', '<', '>', '|' |
| 2915 | 2917 | BadPathName, |
| 2918 | Overflow, | |
| 2916 | 2919 | Unexpected, |
| 2917 | 2920 | } || os.OpenError || SelfExePathError || os.FlockError; |
| 2918 | 2921 | |
| ... | ... | @@ -2991,7 +2994,15 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 { |
| 2991 | 2994 | // TODO could this slice from 0 to out_len instead? |
| 2992 | 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 | 3006 | // OpenBSD doesn't support getting the path of a running process, so try to guess it |
| 2996 | 3007 | if (os.argv.len == 0) |
| 2997 | 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 | 1214 | try testing.expectEqualStrings(expected_output, result); |
| 1215 | 1215 | } |
| 1216 | 1216 | |
| 1217 | /// Returns the extension of the file name (if any). | |
| 1218 | /// This function will search for the file extension (separated by a `.`) and will return the text after the `.`. | |
| 1219 | /// Files that end with `.`, or that start with `.` and have no other `.` in their name, | |
| 1220 | /// are considered to have no extension. | |
| 1217 | /// Searches for a file extension separated by a `.` and returns the string after that `.`. | |
| 1218 | /// Files that end or start with `.` and have no other `.` in their name | |
| 1219 | /// are considered to have no extension, in which case this returns "". | |
| 1221 | 1220 | /// Examples: |
| 1222 | 1221 | /// - `"main.zig"` ⇒ `".zig"` |
| 1223 | 1222 | /// - `"src/main.zig"` ⇒ `".zig"` |
lib/std/http.zig+1| ... | ... | @@ -275,4 +275,5 @@ test { |
| 275 | 275 | _ = Client; |
| 276 | 276 | _ = Method; |
| 277 | 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 | 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 | 648 | try req.response.parse(req.response.parser.header_bytes.items); |
| 650 | 649 | |
| 651 | 650 | if (req.response.status == .switching_protocols) { |
| ... | ... | @@ -765,7 +764,7 @@ pub const Request = struct { |
| 765 | 764 | } |
| 766 | 765 | |
| 767 | 766 | if (has_trail) { |
| 768 | req.response.headers = http.Headers{ .allocator = req.client.allocator, .owned = false }; | |
| 767 | req.response.headers.clearRetainingCapacity(); | |
| 769 | 768 | |
| 770 | 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 | 770 | // This will *only* fail for a malformed trailer. |
| ... | ... | @@ -797,18 +796,18 @@ pub const Request = struct { |
| 797 | 796 | |
| 798 | 797 | /// Write `bytes` to the server. The `transfer_encoding` request header determines how data will be sent. |
| 799 | 798 | pub fn write(req: *Request, bytes: []const u8) WriteError!usize { |
| 800 | switch (req.headers.transfer_encoding) { | |
| 799 | switch (req.transfer_encoding) { | |
| 801 | 800 | .chunked => { |
| 802 | try req.connection.data.conn.writer().print("{x}\r\n", .{bytes.len}); | |
| 803 | try req.connection.data.conn.writeAll(bytes); | |
| 804 | try req.connection.data.conn.writeAll("\r\n"); | |
| 801 | try req.connection.data.buffered.writer().print("{x}\r\n", .{bytes.len}); | |
| 802 | try req.connection.data.buffered.writeAll(bytes); | |
| 803 | try req.connection.data.buffered.writeAll("\r\n"); | |
| 805 | 804 | |
| 806 | 805 | return bytes.len; |
| 807 | 806 | }, |
| 808 | 807 | .content_length => |*len| { |
| 809 | 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 | 811 | len.* -= amt; |
| 813 | 812 | return amt; |
| 814 | 813 | }, |
| ... | ... | @@ -828,7 +827,7 @@ pub const Request = struct { |
| 828 | 827 | /// Finish the body of a request. This notifies the server that you have no more data to send. |
| 829 | 828 | pub fn finish(req: *Request) FinishError!void { |
| 830 | 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 | 831 | .content_length => |len| if (len != 0) return error.MessageNotCompleted, |
| 833 | 832 | .none => {}, |
| 834 | 833 | } |
| ... | ... | @@ -1019,7 +1018,7 @@ pub fn request(client: *Client, method: http.Method, uri: Uri, headers: http.Hea |
| 1019 | 1018 | .status = undefined, |
| 1020 | 1019 | .reason = undefined, |
| 1021 | 1020 | .version = undefined, |
| 1022 | .headers = undefined, | |
| 1021 | .headers = http.Headers{ .allocator = client.allocator, .owned = false }, | |
| 1023 | 1022 | .parser = switch (options.header_strategy) { |
| 1024 | 1023 | .dynamic => |max| proto.HeadersParser.initDynamic(max), |
| 1025 | 1024 | .static => |buf| proto.HeadersParser.initStatic(buf), |
lib/std/http/Headers.zig+73-11| ... | ... | @@ -68,17 +68,7 @@ pub const Headers = struct { |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | pub fn deinit(headers: *Headers) void { |
| 71 | var it = headers.index.iterator(); | |
| 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 | ||
| 71 | headers.deallocateIndexListsAndFields(); | |
| 82 | 72 | headers.index.deinit(headers.allocator); |
| 83 | 73 | headers.list.deinit(headers.allocator); |
| 84 | 74 | |
| ... | ... | @@ -255,6 +245,39 @@ pub const Headers = struct { |
| 255 | 245 | |
| 256 | 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 | 283 | test "Headers.append" { |
| ... | ... | @@ -384,3 +407,42 @@ test "Headers consistency" { |
| 384 | 407 | try h.formatCommaSeparated("foo", writer); |
| 385 | 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 | 336 | headers: http.Headers, |
| 337 | 337 | request: Request, |
| 338 | 338 | |
| 339 | pub fn deinit(res: *Response) void { | |
| 340 | res.server.allocator.destroy(res); | |
| 341 | } | |
| 342 | ||
| 339 | 343 | /// Reset this response to its initial state. This must be called before handling a second request on the same connection. |
| 340 | 344 | pub fn reset(res: *Response) void { |
| 345 | res.request.headers.deinit(); | |
| 346 | res.headers.deinit(); | |
| 347 | ||
| 341 | 348 | switch (res.request.compression) { |
| 342 | 349 | .none => {}, |
| 343 | 350 | .deflate => |*deflate| deflate.deinit(), |
| ... | ... | @@ -356,8 +363,6 @@ pub const Response = struct { |
| 356 | 363 | if (res.request.parser.header_bytes_owned) { |
| 357 | 364 | res.request.parser.header_bytes.deinit(res.server.allocator); |
| 358 | 365 | } |
| 359 | ||
| 360 | res.* = undefined; | |
| 361 | 366 | } else { |
| 362 | 367 | res.request.parser.reset(); |
| 363 | 368 | } |
| ... | ... | @@ -656,3 +661,74 @@ pub fn accept(server: *Server, options: HeaderStrategy) AcceptError!*Response { |
| 656 | 661 | |
| 657 | 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 | 556 | switch (r.state) { |
| 557 | 557 | .invalid => return error.HttpChunkInvalid, |
| 558 | 558 | .chunk_data => if (r.next_chunk_length == 0) { |
| 559 | // The trailer section is formatted identically to the header section. | |
| 560 | r.state = .seen_rn; | |
| 559 | if (std.mem.eql(u8, bconn.peek(), "\r\n")) { | |
| 560 | r.state = .finished; | |
| 561 | } else { | |
| 562 | // The trailer section is formatted identically to the header section. | |
| 563 | r.state = .seen_rn; | |
| 564 | } | |
| 561 | 565 | r.done = true; |
| 562 | 566 | |
| 563 | 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 | 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 | 544 | /// pathname (the name of the library as found for execution), and the |
| 545 | 545 | /// compatibility version number. The pathname must match and the compatibility |
| 546 | 546 | /// number in the user of the library must be greater than or equal to the |
| 547 | 547 | /// library being used. The time stamp is used to record the time a library was |
| 548 | 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 | 550 | pub const dylib = extern struct { |
| 551 | 551 | /// library's pathname (offset pointing at the end of dylib_command) |
| 552 | 552 | name: u32, |
lib/std/math.zig+4-3| ... | ... | @@ -782,7 +782,8 @@ fn testOverflow() !void { |
| 782 | 782 | } |
| 783 | 783 | |
| 784 | 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 | 787 | pub fn absInt(x: anytype) !@TypeOf(x) { |
| 787 | 788 | const T = @TypeOf(x); |
| 788 | 789 | return switch (@typeInfo(T)) { |
| ... | ... | @@ -1015,8 +1016,8 @@ pub inline fn fabs(value: anytype) @TypeOf(value) { |
| 1015 | 1016 | } |
| 1016 | 1017 | |
| 1017 | 1018 | /// Returns the absolute value of the integer parameter. |
| 1018 | /// Result is an unsigned integer. | |
| 1019 | /// See also: `absInt` | |
| 1019 | /// Converts result type to unsigned if needed and returns a value of an unsigned integer type. | |
| 1020 | /// Use `absInt` if you want to keep your integer type signed. | |
| 1020 | 1021 | pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) { |
| 1021 | 1022 | .ComptimeInt => comptime_int, |
| 1022 | 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 | 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 | 228 | /// function used, examine closely - it may be a code smell. |
| 229 | 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 | 231 | pub fn zeroes(comptime T: type) T { |
| 232 | 232 | switch (@typeInfo(T)) { |
| 233 | 233 | .ComptimeInt, .Int, .ComptimeFloat, .Float => { |
lib/std/net.zig+13| ... | ... | @@ -1867,6 +1867,7 @@ pub const StreamServer = struct { |
| 1867 | 1867 | /// Copied from `Options` on `init`. |
| 1868 | 1868 | kernel_backlog: u31, |
| 1869 | 1869 | reuse_address: bool, |
| 1870 | reuse_port: bool, | |
| 1870 | 1871 | |
| 1871 | 1872 | /// `undefined` until `listen` returns successfully. |
| 1872 | 1873 | listen_address: Address, |
| ... | ... | @@ -1881,6 +1882,9 @@ pub const StreamServer = struct { |
| 1881 | 1882 | |
| 1882 | 1883 | /// Enable SO.REUSEADDR on the socket. |
| 1883 | 1884 | reuse_address: bool = false, |
| 1885 | ||
| 1886 | /// Enable SO.REUSEPORT on the socket. | |
| 1887 | reuse_port: bool = false, | |
| 1884 | 1888 | }; |
| 1885 | 1889 | |
| 1886 | 1890 | /// After this call succeeds, resources have been acquired and must |
| ... | ... | @@ -1890,6 +1894,7 @@ pub const StreamServer = struct { |
| 1890 | 1894 | .sockfd = null, |
| 1891 | 1895 | .kernel_backlog = options.kernel_backlog, |
| 1892 | 1896 | .reuse_address = options.reuse_address, |
| 1897 | .reuse_port = options.reuse_port, | |
| 1893 | 1898 | .listen_address = undefined, |
| 1894 | 1899 | }; |
| 1895 | 1900 | } |
| ... | ... | @@ -1920,6 +1925,14 @@ pub const StreamServer = struct { |
| 1920 | 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 | 1937 | var socklen = address.getOsSockLen(); |
| 1925 | 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 | 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 | 254 | fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void { |
| 234 | 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 | 4722 | newp: ?*anyopaque, |
| 4723 | 4723 | newlen: usize, |
| 4724 | 4724 | ) SysCtlError!void { |
| 4725 | if (builtin.os.tag == .wasi) { | |
| 4726 | @panic("unsupported"); // TODO should be compile error, not panic | |
| 4727 | } | |
| 4728 | if (builtin.os.tag == .haiku) { | |
| 4729 | @panic("unsupported"); // TODO should be compile error, not panic | |
| 4725 | if (builtin.os.tag == .wasi or builtin.os.tag == .haiku) { | |
| 4726 | @compileError("unsupported OS"); | |
| 4730 | 4727 | } |
| 4731 | 4728 | |
| 4732 | 4729 | const name_len = math.cast(c_uint, name.len) orelse return error.NameTooLong; |
| ... | ... | @@ -4747,11 +4744,8 @@ pub fn sysctlbynameZ( |
| 4747 | 4744 | newp: ?*anyopaque, |
| 4748 | 4745 | newlen: usize, |
| 4749 | 4746 | ) SysCtlError!void { |
| 4750 | if (builtin.os.tag == .wasi) { | |
| 4751 | @panic("unsupported"); // TODO should be compile error, not panic | |
| 4752 | } | |
| 4753 | if (builtin.os.tag == .haiku) { | |
| 4754 | @panic("unsupported"); // TODO should be compile error, not panic | |
| 4747 | if (builtin.os.tag == .wasi or builtin.os.tag == .haiku) { | |
| 4748 | @compileError("unsupported OS"); | |
| 4755 | 4749 | } |
| 4756 | 4750 | |
| 4757 | 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 | 3464 | pub const WAKE_ALARM = 35; |
| 3465 | 3465 | pub const BLOCK_SUSPEND = 36; |
| 3466 | 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 | 3472 | pub fn valid(x: u8) bool { |
| 3470 | 3473 | return x >= 0 and x <= LAST_CAP; |
lib/std/os/linux/seccomp.zig+1-1| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | //! |
| 21 | 21 | //! 1. Each CPU architecture supported by Linux has its own unique ABI and |
| 22 | 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 | 24 | //! filters cannot be assumed to be portable without consulting documentation |
| 25 | 25 | //! like syscalls(2) and testing on target hardware. This also requires |
| 26 | 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 | 1101 | defer tmp.cleanup(); |
| 1102 | 1102 | |
| 1103 | 1103 | var file = try tmp.dir.createFile("foo", .{}); |
| 1104 | defer file.close(); | |
| 1105 | ||
| 1104 | 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 | 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 | 823 | pub fn args() ArgIterator { |
| 823 | 824 | return ArgIterator.init(); |
| 824 | 825 | } |
| ... | ... | @@ -1162,12 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize { |
| 1162 | 1163 | .linux => { |
| 1163 | 1164 | return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory; |
| 1164 | 1165 | }, |
| 1165 | .freebsd => { | |
| 1166 | .freebsd, .netbsd, .openbsd, .dragonfly, .macos => { | |
| 1166 | 1167 | var physmem: c_ulong = undefined; |
| 1167 | 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 | 1175 | error.NameTooLong, error.UnknownName => unreachable, |
| 1170 | else => |e| return e, | |
| 1176 | else => return error.UnknownTotalSystemMemory, | |
| 1171 | 1177 | }; |
| 1172 | 1178 | return @intCast(usize, physmem); |
| 1173 | 1179 | }, |
lib/std/rand.zig+2| ... | ... | @@ -389,6 +389,8 @@ pub const Random = struct { |
| 389 | 389 | |
| 390 | 390 | /// Randomly selects an index into `proportions`, where the likelihood of each |
| 391 | 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 | 395 | /// This is useful for selecting an item from a slice where weights are not equal. |
| 394 | 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 | 35 | pub fn fileSize(header: Header) !u64 { |
| 36 | 36 | const raw = header.bytes[124..][0..12]; |
| 37 | 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 | 39 | if (rtrimmed.len == 0) return 0; |
| 40 | 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 | 122 | .directory => { |
| 123 | 123 | const file_name = try stripComponents(unstripped_file_name, options.strip_components); |
| 124 | 124 | if (file_name.len != 0) { |
| 125 | try dir.makeDir(file_name); | |
| 125 | try dir.makePath(file_name); | |
| 126 | 126 | } |
| 127 | 127 | }, |
| 128 | 128 | .normal => { |
| 129 | 129 | if (file_size == 0 and unstripped_file_name.len == 0) return; |
| 130 | 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 | 135 | var file = try dir.createFile(file_name, .{}); |
| 133 | 136 | defer file.close(); |
| 134 | 137 |
src/Air.zig+1-1| ... | ... | @@ -681,7 +681,7 @@ pub const Inst = struct { |
| 681 | 681 | /// Uses the `un_op` field. |
| 682 | 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 | 685 | /// Uses the `un_op` field. |
| 686 | 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 | 839 | .slice_open => { |
| 840 | 840 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 841 | 841 | |
| 842 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 843 | const line = gz.astgen.source_line - gz.decl_line; | |
| 844 | const column = gz.astgen.source_column; | |
| 845 | ||
| 842 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 846 | 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 | 845 | const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{ |
| 849 | 846 | .lhs = lhs, |
| 850 | 847 | .start = start, |
| ... | ... | @@ -854,14 +851,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 854 | 851 | .slice => { |
| 855 | 852 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 856 | 853 | |
| 857 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 858 | const line = gz.astgen.source_line - gz.decl_line; | |
| 859 | const column = gz.astgen.source_column; | |
| 860 | ||
| 854 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 861 | 855 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); |
| 862 | 856 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start); |
| 863 | 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 | 859 | const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{ |
| 866 | 860 | .lhs = lhs, |
| 867 | 861 | .start = start, |
| ... | ... | @@ -872,15 +866,12 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 872 | 866 | .slice_sentinel => { |
| 873 | 867 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 874 | 868 | |
| 875 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 876 | const line = gz.astgen.source_line - gz.decl_line; | |
| 877 | const column = gz.astgen.source_column; | |
| 878 | ||
| 869 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 879 | 870 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); |
| 880 | 871 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start); |
| 881 | 872 | const end = if (extra.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end) else .none; |
| 882 | 873 | const sentinel = try expr(gz, scope, .{ .rl = .none }, extra.sentinel); |
| 883 | try emitDbgStmt(gz, line, column); | |
| 874 | try emitDbgStmt(gz, cursor); | |
| 884 | 875 | const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{ |
| 885 | 876 | .lhs = lhs, |
| 886 | 877 | .start = start, |
| ... | ... | @@ -914,20 +905,16 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 914 | 905 | .ref => { |
| 915 | 906 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 916 | 907 | |
| 917 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 918 | const line = gz.astgen.source_line - gz.decl_line; | |
| 919 | const column = gz.astgen.source_column; | |
| 920 | try emitDbgStmt(gz, line, column); | |
| 908 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 909 | try emitDbgStmt(gz, cursor); | |
| 921 | 910 | |
| 922 | 911 | return gz.addUnNode(.optional_payload_safe_ptr, lhs, node); |
| 923 | 912 | }, |
| 924 | 913 | else => { |
| 925 | 914 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); |
| 926 | 915 | |
| 927 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 928 | const line = gz.astgen.source_line - gz.decl_line; | |
| 929 | const column = gz.astgen.source_column; | |
| 930 | try emitDbgStmt(gz, line, column); | |
| 916 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 917 | try emitDbgStmt(gz, cursor); | |
| 931 | 918 | |
| 932 | 919 | return rvalue(gz, ri, try gz.addUnNode(.optional_payload_safe, lhs, node), node); |
| 933 | 920 | }, |
| ... | ... | @@ -3330,23 +3317,17 @@ fn assignOp( |
| 3330 | 3317 | |
| 3331 | 3318 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3332 | 3319 | |
| 3333 | var line: u32 = undefined; | |
| 3334 | var column: u32 = undefined; | |
| 3335 | switch (op_inst_tag) { | |
| 3336 | .add, .sub, .mul, .div, .mod_rem => { | |
| 3337 | maybeAdvanceSourceCursorToMainToken(gz, infix_node); | |
| 3338 | line = gz.astgen.source_line - gz.decl_line; | |
| 3339 | column = gz.astgen.source_column; | |
| 3340 | }, | |
| 3341 | else => {}, | |
| 3342 | } | |
| 3320 | const cursor = switch (op_inst_tag) { | |
| 3321 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, infix_node), | |
| 3322 | else => undefined, | |
| 3323 | }; | |
| 3343 | 3324 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3344 | 3325 | const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node); |
| 3345 | 3326 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = lhs_type } }, node_datas[infix_node].rhs); |
| 3346 | 3327 | |
| 3347 | 3328 | switch (op_inst_tag) { |
| 3348 | 3329 | .add, .sub, .mul, .div, .mod_rem => { |
| 3349 | try emitDbgStmt(gz, line, column); | |
| 3330 | try emitDbgStmt(gz, cursor); | |
| 3350 | 3331 | }, |
| 3351 | 3332 | else => {}, |
| 3352 | 3333 | } |
| ... | ... | @@ -5360,8 +5341,7 @@ fn tryExpr( |
| 5360 | 5341 | if (!parent_gz.is_comptime) { |
| 5361 | 5342 | try emitDbgNode(parent_gz, node); |
| 5362 | 5343 | } |
| 5363 | const try_line = astgen.source_line - parent_gz.decl_line; | |
| 5364 | const try_column = astgen.source_column; | |
| 5344 | const try_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column }; | |
| 5365 | 5345 | |
| 5366 | 5346 | const operand_ri: ResultInfo = switch (ri.rl) { |
| 5367 | 5347 | .ref => .{ .rl = .ref, .ctx = .error_handling_expr }, |
| ... | ... | @@ -5382,7 +5362,7 @@ fn tryExpr( |
| 5382 | 5362 | }; |
| 5383 | 5363 | const err_code = try else_scope.addUnNode(err_tag, operand, node); |
| 5384 | 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 | 5366 | _ = try else_scope.addUnNode(.ret_node, err_code, node); |
| 5387 | 5367 | |
| 5388 | 5368 | try else_scope.setTryBody(try_inst, operand); |
| ... | ... | @@ -5607,10 +5587,8 @@ fn addFieldAccess( |
| 5607 | 5587 | const str_index = try astgen.identAsString(field_ident); |
| 5608 | 5588 | const lhs = try expr(gz, scope, lhs_ri, object_node); |
| 5609 | 5589 | |
| 5610 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5611 | const line = gz.astgen.source_line - gz.decl_line; | |
| 5612 | const column = gz.astgen.source_column; | |
| 5613 | try emitDbgStmt(gz, line, column); | |
| 5590 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5591 | try emitDbgStmt(gz, cursor); | |
| 5614 | 5592 | |
| 5615 | 5593 | return gz.addPlNode(tag, node, Zir.Inst.Field{ |
| 5616 | 5594 | .lhs = lhs, |
| ... | ... | @@ -5630,24 +5608,20 @@ fn arrayAccess( |
| 5630 | 5608 | .ref => { |
| 5631 | 5609 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 5632 | 5610 | |
| 5633 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5634 | const line = gz.astgen.source_line - gz.decl_line; | |
| 5635 | const column = gz.astgen.source_column; | |
| 5611 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5636 | 5612 | |
| 5637 | 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 | 5616 | return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); |
| 5641 | 5617 | }, |
| 5642 | 5618 | else => { |
| 5643 | 5619 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); |
| 5644 | 5620 | |
| 5645 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5646 | const line = gz.astgen.source_line - gz.decl_line; | |
| 5647 | const column = gz.astgen.source_column; | |
| 5621 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5648 | 5622 | |
| 5649 | 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 | 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 | 5648 | } |
| 5675 | 5649 | |
| 5676 | 5650 | const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node); |
| 5677 | var line: u32 = undefined; | |
| 5678 | var column: u32 = undefined; | |
| 5679 | switch (op_inst_tag) { | |
| 5680 | .add, .sub, .mul, .div, .mod_rem => { | |
| 5681 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 5682 | line = gz.astgen.source_line - gz.decl_line; | |
| 5683 | column = gz.astgen.source_column; | |
| 5684 | }, | |
| 5685 | else => {}, | |
| 5686 | } | |
| 5651 | const cursor = switch (op_inst_tag) { | |
| 5652 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, node), | |
| 5653 | else => undefined, | |
| 5654 | }; | |
| 5687 | 5655 | const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node); |
| 5688 | 5656 | |
| 5689 | 5657 | switch (op_inst_tag) { |
| 5690 | 5658 | .add, .sub, .mul, .div, .mod_rem => { |
| 5691 | try emitDbgStmt(gz, line, column); | |
| 5659 | try emitDbgStmt(gz, cursor); | |
| 5692 | 5660 | }, |
| 5693 | 5661 | else => {}, |
| 5694 | 5662 | } |
| ... | ... | @@ -6787,14 +6755,15 @@ fn switchExpr( |
| 6787 | 6755 | } |
| 6788 | 6756 | |
| 6789 | 6757 | const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none }; |
| 6758 | ||
| 6790 | 6759 | astgen.advanceSourceCursorToNode(operand_node); |
| 6791 | const operand_line = astgen.source_line - parent_gz.decl_line; | |
| 6792 | const operand_column = astgen.source_column; | |
| 6760 | const operand_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column }; | |
| 6761 | ||
| 6793 | 6762 | const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node); |
| 6794 | 6763 | const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond; |
| 6795 | 6764 | const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node); |
| 6796 | 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 | 6767 | // We need the type of the operand to use as the result location for all the prong items. |
| 6799 | 6768 | const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node); |
| 6800 | 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 | 7123 | if (!gz.is_comptime) { |
| 7155 | 7124 | try emitDbgNode(gz, node); |
| 7156 | 7125 | } |
| 7157 | const ret_line = astgen.source_line - gz.decl_line; | |
| 7158 | const ret_column = astgen.source_column; | |
| 7126 | const ret_lc = LineColumn{ astgen.source_line - gz.decl_line, astgen.source_column }; | |
| 7159 | 7127 | |
| 7160 | 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 | 7147 | const defer_counts = countDefers(defer_outer, scope); |
| 7180 | 7148 | if (!defer_counts.need_err_code) { |
| 7181 | 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 | 7151 | _ = try gz.addStrTok(.ret_err_value, err_name_str_index, ident_token); |
| 7184 | 7152 | return Zir.Inst.Ref.unreachable_value; |
| 7185 | 7153 | } |
| 7186 | 7154 | const err_code = try gz.addStrTok(.ret_err_value_code, err_name_str_index, ident_token); |
| 7187 | 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 | 7157 | _ = try gz.addUnNode(.ret_node, err_code, node); |
| 7190 | 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 | 7178 | // As our last action before the return, "pop" the error trace if needed |
| 7211 | 7179 | _ = try gz.addRestoreErrRetIndex(.ret, .always); |
| 7212 | 7180 | |
| 7213 | try emitDbgStmt(gz, ret_line, ret_column); | |
| 7181 | try emitDbgStmt(gz, ret_lc); | |
| 7214 | 7182 | try gz.addRet(ri, operand, node); |
| 7215 | 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 | 7186 | // Value is always an error. Emit both error defers and regular defers. |
| 7219 | 7187 | const err_code = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| 7220 | 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 | 7190 | try gz.addRet(ri, operand, node); |
| 7223 | 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 | 7195 | if (!defer_counts.have_err) { |
| 7228 | 7196 | // Only regular defers; no branch needed. |
| 7229 | 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 | 7200 | // As our last action before the return, "pop" the error trace if needed |
| 7233 | 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 | 7218 | // As our last action before the return, "pop" the error trace if needed |
| 7251 | 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 | 7222 | try then_scope.addRet(ri, operand, node); |
| 7255 | 7223 | |
| 7256 | 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 | 7228 | .both = try else_scope.addUnNode(.err_union_code, result, node), |
| 7261 | 7229 | }; |
| 7262 | 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 | 7232 | try else_scope.addRet(ri, operand, node); |
| 7265 | 7233 | |
| 7266 | 7234 | try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0); |
| ... | ... | @@ -8174,6 +8142,7 @@ fn builtinCall( |
| 8174 | 8142 | .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node), |
| 8175 | 8143 | .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node), |
| 8176 | 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 | 8147 | .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info), |
| 8179 | 8148 | .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of), |
| ... | ... | @@ -8649,11 +8618,14 @@ fn typeCast( |
| 8649 | 8618 | rhs_node: Ast.Node.Index, |
| 8650 | 8619 | tag: Zir.Inst.Tag, |
| 8651 | 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 | 8626 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8655 | .lhs = try typeExpr(gz, scope, lhs_node), | |
| 8656 | .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node), | |
| 8627 | .lhs = result_type, | |
| 8628 | .rhs = operand, | |
| 8657 | 8629 | }); |
| 8658 | 8630 | return rvalue(gz, ri, result, node); |
| 8659 | 8631 | } |
| ... | ... | @@ -8680,14 +8652,15 @@ fn simpleUnOp( |
| 8680 | 8652 | operand_node: Ast.Node.Index, |
| 8681 | 8653 | tag: Zir.Inst.Tag, |
| 8682 | 8654 | ) InnerError!Zir.Inst.Ref { |
| 8683 | switch (tag) { | |
| 8684 | .tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node), | |
| 8685 | else => {}, | |
| 8686 | } | |
| 8655 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 8687 | 8656 | const operand = if (tag == .compile_error) |
| 8688 | 8657 | try comptimeExpr(gz, scope, operand_ri, operand_node) |
| 8689 | 8658 | else |
| 8690 | 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 | 8664 | const result = try gz.addUnNode(tag, operand, node); |
| 8692 | 8665 | return rvalue(gz, ri, result, node); |
| 8693 | 8666 | } |
| ... | ... | @@ -8759,12 +8732,12 @@ fn divBuiltin( |
| 8759 | 8732 | rhs_node: Ast.Node.Index, |
| 8760 | 8733 | tag: Zir.Inst.Tag, |
| 8761 | 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{ | |
| 8765 | .lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node), | |
| 8766 | .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node), | |
| 8767 | }); | |
| 8739 | try emitDbgStmt(gz, cursor); | |
| 8740 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); | |
| 8768 | 8741 | return rvalue(gz, ri, result, node); |
| 8769 | 8742 | } |
| 8770 | 8743 | |
| ... | ... | @@ -8813,23 +8786,21 @@ fn shiftOp( |
| 8813 | 8786 | rhs_node: Ast.Node.Index, |
| 8814 | 8787 | tag: Zir.Inst.Tag, |
| 8815 | 8788 | ) InnerError!Zir.Inst.Ref { |
| 8816 | var line = gz.astgen.source_line - gz.decl_line; | |
| 8817 | var column = gz.astgen.source_column; | |
| 8818 | 8789 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); |
| 8819 | 8790 | |
| 8820 | switch (gz.astgen.tree.nodes.items(.tag)[node]) { | |
| 8821 | .shl, .shr => { | |
| 8822 | maybeAdvanceSourceCursorToMainToken(gz, node); | |
| 8823 | line = gz.astgen.source_line - gz.decl_line; | |
| 8824 | column = gz.astgen.source_column; | |
| 8825 | }, | |
| 8826 | else => {}, | |
| 8827 | } | |
| 8791 | const cursor = switch (gz.astgen.tree.nodes.items(.tag)[node]) { | |
| 8792 | .shl, .shr => maybeAdvanceSourceCursorToMainToken(gz, node), | |
| 8793 | else => undefined, | |
| 8794 | }; | |
| 8828 | 8795 | |
| 8829 | 8796 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); |
| 8830 | 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 | 8804 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8834 | 8805 | .lhs = lhs, |
| 8835 | 8806 | .rhs = rhs, |
| ... | ... | @@ -12593,16 +12564,20 @@ fn detectLocalShadowing( |
| 12593 | 12564 | }; |
| 12594 | 12565 | } |
| 12595 | 12566 | |
| 12567 | const LineColumn = struct { u32, u32 }; | |
| 12568 | ||
| 12596 | 12569 | /// Advances the source cursor to the main token of `node` if not in comptime scope. |
| 12597 | 12570 | /// Usually paired with `emitDbgStmt`. |
| 12598 | fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void { | |
| 12599 | if (gz.is_comptime) return; | |
| 12571 | fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineColumn { | |
| 12572 | if (gz.is_comptime) return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; | |
| 12600 | 12573 | |
| 12601 | 12574 | const tree = gz.astgen.tree; |
| 12602 | 12575 | const token_starts = tree.tokens.items(.start); |
| 12603 | 12576 | const main_tokens = tree.nodes.items(.main_token); |
| 12604 | 12577 | const node_start = token_starts[main_tokens[node]]; |
| 12605 | 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 | 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 | 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 | 12785 | if (gz.is_comptime) return; |
| 12811 | 12786 | |
| 12812 | 12787 | _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{ |
| 12813 | 12788 | .dbg_stmt = .{ |
| 12814 | .line = line, | |
| 12815 | .column = column, | |
| 12789 | .line = lc[0], | |
| 12790 | .column = lc[1], | |
| 12816 | 12791 | }, |
| 12817 | 12792 | } }); |
| 12818 | 12793 | } |
src/Autodoc.zig+2-2| ... | ... | @@ -4076,7 +4076,7 @@ fn analyzeFancyFunction( |
| 4076 | 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 | 4080 | // actually don't have an ast_node reserved for us, but since |
| 4081 | 4081 | // we don't have a name, we don't need it. |
| 4082 | 4082 | const src = if (fn_info.body.len == 0) 0 else self_ast_node_index; |
| ... | ... | @@ -4229,7 +4229,7 @@ fn analyzeFunction( |
| 4229 | 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 | 4233 | // actually don't have an ast_node reserved for us, but since |
| 4234 | 4234 | // we don't have a name, we don't need it. |
| 4235 | 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 | 58 | has_decl, |
| 59 | 59 | has_field, |
| 60 | 60 | import, |
| 61 | in_comptime, | |
| 61 | 62 | int_cast, |
| 62 | 63 | int_to_enum, |
| 63 | 64 | int_to_error, |
| ... | ... | @@ -560,6 +561,13 @@ pub const list = list: { |
| 560 | 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 | 572 | "@intCast", |
| 565 | 573 | .{ |
src/Module.zig+1-1| ... | ... | @@ -6626,7 +6626,7 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool { |
| 6626 | 6626 | .safety_check_formatted => mod.comp.bin_file.options.use_llvm, |
| 6627 | 6627 | .error_return_trace => mod.comp.bin_file.options.use_llvm, |
| 6628 | 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 | 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 | 1166 | .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode), |
| 1167 | 1167 | .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode), |
| 1168 | 1168 | .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode), |
| 1169 | .in_comptime => try sema.zirInComptime( block), | |
| 1169 | 1170 | // zig fmt: on |
| 1170 | 1171 | |
| 1171 | 1172 | .fence => { |
| ... | ... | @@ -4155,7 +4156,7 @@ fn validateUnionInit( |
| 4155 | 4156 | const msg = try sema.errMsg( |
| 4156 | 4157 | block, |
| 4157 | 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 | 4162 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -9646,7 +9647,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 9646 | 9647 | .Union => "union", |
| 9647 | 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 | 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 | 9710 | .Union => "union", |
| 9710 | 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 | 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 | 19627 | } |
| 19627 | 19628 | |
| 19628 | 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 | 19631 | if (!ptr_ty.isAllowzeroPtr()) { |
| 19631 | 19632 | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); |
| 19632 | 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 | 19853 | |
| 19853 | 19854 | try sema.requireRuntimeBlock(block, src, null); |
| 19854 | 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 | 19858 | const ptr_int = try block.addUnOp(.ptrtoint, ptr); |
| 19858 | 19859 | const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize); |
| ... | ... | @@ -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 | 22482 | fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void { |
| 22470 | 22483 | if (block.is_comptime) { |
| 22471 | 22484 | const msg = msg: { |
| ... | ... | @@ -23738,7 +23751,6 @@ fn fieldCallBind( |
| 23738 | 23751 | { |
| 23739 | 23752 | const first_param_type = decl_type.fnParamType(0); |
| 23740 | 23753 | const first_param_tag = first_param_type.tag(); |
| 23741 | var opt_buf: Type.Payload.ElemType = undefined; | |
| 23742 | 23754 | // zig fmt: off |
| 23743 | 23755 | if (first_param_tag == .var_args_param or |
| 23744 | 23756 | first_param_tag == .generic_poison or ( |
| ... | ... | @@ -23764,17 +23776,29 @@ fn fieldCallBind( |
| 23764 | 23776 | .arg0_inst = deref, |
| 23765 | 23777 | }); |
| 23766 | 23778 | return sema.addConstant(ty, value); |
| 23767 | } else if (first_param_tag != .generic_poison and first_param_type.zigTypeTag() == .Optional and | |
| 23768 | first_param_type.optionalChild(&opt_buf).eql(concrete_ty, sema.mod)) | |
| 23769 | { | |
| 23770 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); | |
| 23771 | const ty = Type.Tag.bound_fn.init(); | |
| 23772 | const value = try Value.Tag.bound_fn.create(arena, .{ | |
| 23773 | .func_inst = decl_val, | |
| 23774 | .arg0_inst = deref, | |
| 23775 | }); | |
| 23776 | return sema.addConstant(ty, value); | |
| 23777 | } else if (first_param_tag != .generic_poison and first_param_type.zigTypeTag() == .ErrorUnion and | |
| 23779 | } else if (first_param_type.zigTypeTag() == .Optional) { | |
| 23780 | var opt_buf: Type.Payload.ElemType = undefined; | |
| 23781 | const child = first_param_type.optionalChild(&opt_buf); | |
| 23782 | if (child.eql(concrete_ty, sema.mod)) { | |
| 23783 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); | |
| 23784 | const ty = Type.Tag.bound_fn.init(); | |
| 23785 | const value = try Value.Tag.bound_fn.create(arena, .{ | |
| 23786 | .func_inst = decl_val, | |
| 23787 | .arg0_inst = deref, | |
| 23788 | }); | |
| 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 | 23802 | first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod)) |
| 23779 | 23803 | { |
| 23780 | 23804 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); |
| ... | ... | @@ -26434,7 +26458,7 @@ fn coerceVarArgParam( |
| 26434 | 26458 | .ComptimeInt, .ComptimeFloat => return sema.fail( |
| 26435 | 26459 | block, |
| 26436 | 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 | 26464 | .Fn => blk: { |
| ... | ... | @@ -27718,7 +27742,7 @@ fn coerceCompatiblePtrs( |
| 27718 | 27742 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 27719 | 27743 | const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero(); |
| 27720 | 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 | 27747 | const actual_ptr = if (inst_ty.isSlice()) |
| 27724 | 27748 | try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty) |
| ... | ... | @@ -27891,7 +27915,7 @@ fn coerceAnonStructToUnion( |
| 27891 | 27915 | const msg = if (field_count > 1) try sema.errMsg( |
| 27892 | 27916 | block, |
| 27893 | 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 | 27920 | ) else try sema.errMsg( |
| 27897 | 27921 | block, |
src/Zir.zig+5-2| ... | ... | @@ -1994,10 +1994,10 @@ pub const Inst = struct { |
| 1994 | 1994 | /// Implement builtin `@cVaArg`. |
| 1995 | 1995 | /// `operand` is payload index to `BinNode`. |
| 1996 | 1996 | c_va_arg, |
| 1997 | /// Implement builtin `@cVaStart`. | |
| 1997 | /// Implement builtin `@cVaCopy`. | |
| 1998 | 1998 | /// `operand` is payload index to `UnNode`. |
| 1999 | 1999 | c_va_copy, |
| 2000 | /// Implement builtin `@cVaStart`. | |
| 2000 | /// Implement builtin `@cVaEnd`. | |
| 2001 | 2001 | /// `operand` is payload index to `UnNode`. |
| 2002 | 2002 | c_va_end, |
| 2003 | 2003 | /// Implement builtin `@cVaStart`. |
| ... | ... | @@ -2018,6 +2018,9 @@ pub const Inst = struct { |
| 2018 | 2018 | /// Implements the `@workGroupId` builtin. |
| 2019 | 2019 | /// `operand` is payload index to `UnNode`. |
| 2020 | 2020 | work_group_id, |
| 2021 | /// Implements the `@inComptime` builtin. | |
| 2022 | /// `operand` is `src_node: i32`. | |
| 2023 | in_comptime, | |
| 2021 | 2024 | |
| 2022 | 2025 | pub const InstData = struct { |
| 2023 | 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 | 1946 | .ret_addr => func.airRetAddr(inst), |
| 1947 | 1947 | .tag_name => func.airTagName(inst), |
| 1948 | 1948 | |
| 1949 | .error_set_has_value => func.airErrorSetHasValue(inst), | |
| 1950 | ||
| 1949 | 1951 | .mul_sat, |
| 1950 | 1952 | .mod, |
| 1951 | 1953 | .assembly, |
| ... | ... | @@ -1967,7 +1969,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1967 | 1969 | .set_err_return_trace, |
| 1968 | 1970 | .save_err_return_trace_index, |
| 1969 | 1971 | .is_named_enum_value, |
| 1970 | .error_set_has_value, | |
| 1971 | 1972 | .addrspace_cast, |
| 1972 | 1973 | .vector_store_elem, |
| 1973 | 1974 | .c_va_arg, |
| ... | ... | @@ -3338,9 +3339,14 @@ fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3338 | 3339 | fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3339 | 3340 | const un_op = func.air.instructions.items(.data)[inst].un_op; |
| 3340 | 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; | |
| 3343 | return func.fail("TODO implement airCmpLtErrorsLen for wasm", .{}); | |
| 3345 | try func.emitWValue(operand); | |
| 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 | 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 | 6516 | const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, func.target); |
| 6511 | 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 | 460 | |
| 461 | 461 | pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr; |
| 462 | 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 | 468 | pub const FieldDecl = opaque { |
| ... | ... | @@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque { |
| 1053 | 1056 | pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller; |
| 1054 | 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 | 1065 | pub const getNumInits = ZigClangInitListExpr_getNumInits; |
| 1057 | 1066 | extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint; |
| 1058 | 1067 |
src/link/NvPtx.zig+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | //! NVidia PTX (Paralle Thread Execution) | |
| 1 | //! NVidia PTX (Parallel Thread Execution) | |
| 2 | 2 | //! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html |
| 3 | 3 | //! For this we rely on the nvptx backend of LLVM |
| 4 | 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 | 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 | 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 | 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 | 2230 | /// Creates a function body for the `__wasm_call_ctors` symbol. |
| 2189 | 2231 | /// Loops over all constructors found in `init_funcs` and calls them |
| 2190 | 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 | 3359 | // So we can rebuild the binary file on each incremental update |
| 3318 | 3360 | defer wasm.resetState(); |
| 3319 | 3361 | try wasm.setupInitFunctions(); |
| 3362 | try wasm.setupErrorsLen(); | |
| 3320 | 3363 | try wasm.setupStart(); |
| 3321 | 3364 | try wasm.setupImports(); |
| 3322 | 3365 | if (wasm.base.options.module) |mod| { |
src/main.zig+2-2| ... | ... | @@ -402,8 +402,8 @@ const usage_build_generic = |
| 402 | 402 | \\ --name [name] Override root name (not a file path) |
| 403 | 403 | \\ -O [mode] Choose what to optimize for |
| 404 | 404 | \\ Debug (default) Optimizations off, safety on |
| 405 | \\ ReleaseFast Optimizations on, safety off | |
| 406 | \\ ReleaseSafe Optimizations on, safety on | |
| 405 | \\ ReleaseFast Optimize for performance, safety off | |
| 406 | \\ ReleaseSafe Optimize for performance, safety on | |
| 407 | 407 | \\ ReleaseSmall Optimize for small binary, safety off |
| 408 | 408 | \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name |
| 409 | 409 | \\ deps: [dep],[dep],... |
src/print_zir.zig+1| ... | ... | @@ -466,6 +466,7 @@ const Writer = struct { |
| 466 | 466 | .frame_address, |
| 467 | 467 | .breakpoint, |
| 468 | 468 | .c_va_start, |
| 469 | .in_comptime, | |
| 469 | 470 | => try self.writeExtNode(stream, extended), |
| 470 | 471 | |
| 471 | 472 | .builtin_src => { |
src/translate_c.zig+27-8| ... | ... | @@ -2697,6 +2697,13 @@ fn transInitListExprArray( |
| 2697 | 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 | 2707 | const init_node = if (init_count != 0) blk: { |
| 2701 | 2708 | const init_list = try c.arena.alloc(Node, init_count); |
| 2702 | 2709 | |
| ... | ... | @@ -2714,6 +2721,7 @@ fn transInitListExprArray( |
| 2714 | 2721 | break :blk init_node; |
| 2715 | 2722 | } else null; |
| 2716 | 2723 | |
| 2724 | assert(expr.hasArrayFiller()); | |
| 2717 | 2725 | const filler_val_expr = expr.getArrayFiller(); |
| 2718 | 2726 | const filler_node = try Tag.array_filler.create(c.arena, .{ |
| 2719 | 2727 | .type = child_type, |
| ... | ... | @@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void { |
| 4176 | 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 | 4198 | /// Translate a qualtype for a variable with an initializer. This only matters |
| 4180 | 4199 | /// for incomplete arrays, since the initializer determines the size of the array. |
| 4181 | 4200 | fn transQualTypeInitialized( |
| ... | ... | @@ -4193,18 +4212,18 @@ fn transQualTypeInitialized( |
| 4193 | 4212 | switch (decl_init.getStmtClass()) { |
| 4194 | 4213 | .StringLiteralClass => { |
| 4195 | 4214 | const string_lit = @ptrCast(*const clang.StringLiteral, decl_init); |
| 4196 | const string_lit_size = string_lit.getLength(); | |
| 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 }); | |
| 4215 | return transQualTypeInitializedStringLiteral(c, elem_ty, string_lit); | |
| 4204 | 4216 | }, |
| 4205 | 4217 | .InitListExprClass => { |
| 4206 | 4218 | const init_expr = @ptrCast(*const clang.InitListExpr, decl_init); |
| 4207 | 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 | 4227 | return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty }); |
| 4209 | 4228 | }, |
| 4210 | 4229 | else => {}, |
src/zig_clang.cpp+16| ... | ... | @@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE |
| 2382 | 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 | 2391 | const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) { |
| 2386 | 2392 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); |
| 2387 | 2393 | const clang::Expr *result = casted->getInit(i); |
| ... | ... | @@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx |
| 2394 | 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 | 2413 | const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) { |
| 2398 | 2414 | auto casted = reinterpret_cast<const clang::InitListExpr *>(self); |
| 2399 | 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 | 1220 | ZigClangAPFloat **result, const struct ZigClangASTContext *ctx); |
| 1221 | 1221 | ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *, |
| 1222 | 1222 | struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *); |
| 1223 | ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self); | |
| 1223 | 1224 | |
| 1224 | 1225 | ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned); |
| 1225 | 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 | 1229 | ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *); |
| 1227 | 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 | 253 | #define zig_concat(lhs, rhs) lhs##rhs |
| 254 | 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 | 256 | #if __STDC_VERSION__ >= 201112L |
| 348 | 257 | #define zig_noreturn _Noreturn |
| 349 | 258 | #elif zig_has_attribute(noreturn) || defined(zig_gnuc) |
| ... | ... | @@ -502,15 +411,6 @@ typedef ptrdiff_t intptr_t; |
| 502 | 411 | |
| 503 | 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 | 414 | #define zig_minInt_i8 INT8_MIN |
| 515 | 415 | #define zig_maxInt_i8 INT8_MAX |
| 516 | 416 | #define zig_minInt_u8 UINT8_C(0) |
| ... | ... | @@ -534,24 +434,24 @@ typedef ptrdiff_t intptr_t; |
| 534 | 434 | #define zig_minInt_u(w, bits) zig_intLimit(u, w, min, bits) |
| 535 | 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 | 438 | static inline Type zig_##operation(Type lhs, RhsType rhs) { \ |
| 539 | 439 | return lhs operator rhs; \ |
| 540 | 440 | } |
| 541 | #define zig_int_basic_operator(Type, operation, operator) \ | |
| 542 | zig_int_operator(Type, Type, operation, operator) | |
| 543 | #define zig_int_shift_operator(Type, operation, operator) \ | |
| 544 | zig_int_operator(Type, uint8_t, operation, operator) | |
| 441 | #define zig_basic_operator(Type, operation, operator) \ | |
| 442 | zig_operator(Type, Type, operation, operator) | |
| 443 | #define zig_shift_operator(Type, operation, operator) \ | |
| 444 | zig_operator(Type, uint8_t, operation, operator) | |
| 545 | 445 | #define zig_int_helpers(w) \ |
| 546 | zig_int_basic_operator(uint##w##_t, and_u##w, &) \ | |
| 547 | zig_int_basic_operator( int##w##_t, and_i##w, &) \ | |
| 548 | zig_int_basic_operator(uint##w##_t, or_u##w, |) \ | |
| 549 | zig_int_basic_operator( int##w##_t, or_i##w, |) \ | |
| 550 | zig_int_basic_operator(uint##w##_t, xor_u##w, ^) \ | |
| 551 | zig_int_basic_operator( int##w##_t, xor_i##w, ^) \ | |
| 552 | zig_int_shift_operator(uint##w##_t, shl_u##w, <<) \ | |
| 553 | zig_int_shift_operator( int##w##_t, shl_i##w, <<) \ | |
| 554 | zig_int_shift_operator(uint##w##_t, shr_u##w, >>) \ | |
| 446 | zig_basic_operator(uint##w##_t, and_u##w, &) \ | |
| 447 | zig_basic_operator( int##w##_t, and_i##w, &) \ | |
| 448 | zig_basic_operator(uint##w##_t, or_u##w, |) \ | |
| 449 | zig_basic_operator( int##w##_t, or_i##w, |) \ | |
| 450 | zig_basic_operator(uint##w##_t, xor_u##w, ^) \ | |
| 451 | zig_basic_operator( int##w##_t, xor_i##w, ^) \ | |
| 452 | zig_shift_operator(uint##w##_t, shl_u##w, <<) \ | |
| 453 | zig_shift_operator( int##w##_t, shl_i##w, <<) \ | |
| 454 | zig_shift_operator(uint##w##_t, shr_u##w, >>) \ | |
| 555 | 455 | \ |
| 556 | 456 | static inline int##w##_t zig_shr_i##w(int##w##_t lhs, uint8_t rhs) { \ |
| 557 | 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 | 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 | 481 | static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \ |
| 582 | 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 | 487 | static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \ |
| 588 | 488 | int##w##_t rem = lhs % rhs; \ |
| ... | ... | @@ -1253,8 +1153,8 @@ typedef signed __int128 zig_i128; |
| 1253 | 1153 | #define zig_lo_u128(val) ((uint64_t)((val) >> 0)) |
| 1254 | 1154 | #define zig_hi_i128(val) (( int64_t)((val) >> 64)) |
| 1255 | 1155 | #define zig_lo_i128(val) ((uint64_t)((val) >> 0)) |
| 1256 | #define zig_bitcast_u128(val) ((zig_u128)(val)) | |
| 1257 | #define zig_bitcast_i128(val) ((zig_i128)(val)) | |
| 1156 | #define zig_bitCast_u128(val) ((zig_u128)(val)) | |
| 1157 | #define zig_bitCast_i128(val) ((zig_i128)(val)) | |
| 1258 | 1158 | #define zig_cmp_int128(Type) \ |
| 1259 | 1159 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1260 | 1160 | return (lhs > rhs) - (lhs < rhs); \ |
| ... | ... | @@ -1288,8 +1188,8 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; |
| 1288 | 1188 | #define zig_lo_u128(val) ((val).lo) |
| 1289 | 1189 | #define zig_hi_i128(val) ((val).hi) |
| 1290 | 1190 | #define zig_lo_i128(val) ((val).lo) |
| 1291 | #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) | |
| 1191 | #define zig_bitCast_u128(val) zig_make_u128((uint64_t)(val).hi, (val).lo) | |
| 1192 | #define zig_bitCast_i128(val) zig_make_i128(( int64_t)(val).hi, (val).lo) | |
| 1293 | 1193 | #define zig_cmp_int128(Type) \ |
| 1294 | 1194 | static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1295 | 1195 | return (lhs.hi == rhs.hi) \ |
| ... | ... | @@ -1303,9 +1203,6 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; |
| 1303 | 1203 | |
| 1304 | 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 | 1206 | #define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64) |
| 1310 | 1207 | #define zig_maxInt_u128 zig_make_u128(zig_maxInt_u64, zig_maxInt_u64) |
| 1311 | 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 | 1363 | } |
| 1467 | 1364 | |
| 1468 | 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 | 1369 | zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); |
| 1473 | 1370 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1474 | 1371 | return __udivti3(lhs, rhs); |
| 1475 | }; | |
| 1372 | } | |
| 1476 | 1373 | |
| 1477 | 1374 | zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs); |
| 1478 | 1375 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1479 | 1376 | return __divti3(lhs, rhs); |
| 1480 | }; | |
| 1377 | } | |
| 1481 | 1378 | |
| 1482 | 1379 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); |
| 1483 | 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 | 1400 | #define zig_div_floor_u128 zig_div_trunc_u128 |
| 1504 | 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 | 1403 | static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1511 | 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 | 1431 | } |
| 1539 | 1432 | |
| 1540 | 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 | 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 | 1439 | } |
| 1547 | 1440 | |
| 1548 | 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 | 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 | 1447 | } |
| 1555 | 1448 | |
| 1556 | 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 | 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 | 1455 | } |
| 1563 | 1456 | |
| 1564 | 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 | 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 | 1590 | |
| 1698 | 1591 | static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) { |
| 1699 | 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 | 1594 | return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) && |
| 1702 | 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 | 1604 | |
| 1712 | 1605 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { |
| 1713 | 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 | 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 | 1648 | } |
| 1756 | 1649 | |
| 1757 | 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 | 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 | 1657 | } |
| 1765 | 1658 | |
| 1766 | 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 | 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 | 1666 | } |
| 1774 | 1667 | |
| 1775 | 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 | 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 | 1681 | } |
| 1789 | 1682 | |
| 1790 | 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 | 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 | 1691 | } |
| 1799 | 1692 | |
| 1800 | 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 | 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 | 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 | 2105 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { |
| 1976 | 2106 | uint8_t *res_bytes = res; |
| 1977 | 2107 | const uint8_t *lhs_bytes = lhs; |
| ... | ... | @@ -2827,24 +2957,20 @@ long double __cdecl nanl(char const* input); |
| 2827 | 2957 | #endif |
| 2828 | 2958 | |
| 2829 | 2959 | #if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gnuc) |
| 2830 | #define zig_has_float_builtins 1 | |
| 2831 | #define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16(__builtin_##name, )(arg) | |
| 2832 | #define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32(__builtin_##name, )(arg) | |
| 2833 | #define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64(__builtin_##name, )(arg) | |
| 2834 | #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80(__builtin_##name, )(arg) | |
| 2960 | #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) | |
| 2962 | #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) | |
| 2835 | 2964 | #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) |
| 2836 | 2965 | #else |
| 2837 | #define zig_has_float_builtins 0 | |
| 2838 | #define zig_make_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr) | |
| 2839 | #define zig_make_special_f32(sign, name, arg, repr) zig_float_from_repr_f32(repr) | |
| 2840 | #define zig_make_special_f64(sign, name, arg, repr) zig_float_from_repr_f64(repr) | |
| 2841 | #define zig_make_special_f80(sign, name, arg, repr) zig_float_from_repr_f80(repr) | |
| 2842 | #define zig_make_special_f128(sign, name, arg, repr) zig_float_from_repr_f128(repr) | |
| 2966 | #define zig_make_special_f16(sign, name, arg, repr) zig_bitCast_f16 (repr) | |
| 2967 | #define zig_make_special_f32(sign, name, arg, repr) zig_bitCast_f32 (repr) | |
| 2968 | #define zig_make_special_f64(sign, name, arg, repr) zig_bitCast_f64 (repr) | |
| 2969 | #define zig_make_special_f80(sign, name, arg, repr) zig_bitCast_f80 (repr) | |
| 2970 | #define zig_make_special_f128(sign, name, arg, repr) zig_bitCast_f128(repr) | |
| 2843 | 2971 | #endif |
| 2844 | 2972 | |
| 2845 | 2973 | #define zig_has_f16 1 |
| 2846 | #define zig_bitSizeOf_f16 16 | |
| 2847 | typedef uint16_t zig_repr_f16; | |
| 2848 | 2974 | #define zig_libc_name_f16(name) __##name##h |
| 2849 | 2975 | #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) |
| 2850 | 2976 | #if FLT_MANT_DIG == 11 |
| ... | ... | @@ -2854,10 +2980,6 @@ typedef float zig_f16; |
| 2854 | 2980 | typedef double zig_f16; |
| 2855 | 2981 | #define zig_make_f16(fp, repr) fp |
| 2856 | 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 | 2983 | typedef long double zig_f16; |
| 2862 | 2984 | #define zig_make_f16(fp, repr) fp##l |
| 2863 | 2985 | #elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc)) |
| ... | ... | @@ -2869,8 +2991,8 @@ typedef __fp16 zig_f16; |
| 2869 | 2991 | #else |
| 2870 | 2992 | #undef zig_has_f16 |
| 2871 | 2993 | #define zig_has_f16 0 |
| 2872 | #define zig_bitSizeOf_repr_f16 16 | |
| 2873 | typedef zig_repr_f16 zig_f16; | |
| 2994 | #define zig_repr_f16 u16 | |
| 2995 | typedef uint16_t zig_f16; | |
| 2874 | 2996 | #define zig_make_f16(fp, repr) repr |
| 2875 | 2997 | #undef zig_make_special_f16 |
| 2876 | 2998 | #define zig_make_special_f16(sign, name, arg, repr) repr |
| ... | ... | @@ -2878,15 +3000,12 @@ typedef zig_repr_f16 zig_f16; |
| 2878 | 3000 | #define zig_init_special_f16(sign, name, arg, repr) repr |
| 2879 | 3001 | #endif |
| 2880 | 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 | 3004 | #else |
| 2883 | 3005 | typedef zig_f16 zig_compiler_rt_f16; |
| 2884 | 3006 | #endif |
| 2885 | #define zig_compiler_rt_abbrev_zig_compiler_rt_f16 zig_compiler_rt_abbrev_zig_f16 | |
| 2886 | 3007 | |
| 2887 | 3008 | #define zig_has_f32 1 |
| 2888 | #define zig_bitSizeOf_f32 32 | |
| 2889 | typedef uint32_t zig_repr_f32; | |
| 2890 | 3009 | #define zig_libc_name_f32(name) name##f |
| 2891 | 3010 | #if _MSC_VER |
| 2892 | 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 | 3019 | typedef double zig_f32; |
| 2901 | 3020 | #define zig_make_f32(fp, repr) fp |
| 2902 | 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 | 3022 | typedef long double zig_f32; |
| 2908 | 3023 | #define zig_make_f32(fp, repr) fp##l |
| 2909 | 3024 | #elif FLT32_MANT_DIG == 24 |
| ... | ... | @@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32; |
| 2912 | 3027 | #else |
| 2913 | 3028 | #undef zig_has_f32 |
| 2914 | 3029 | #define zig_has_f32 0 |
| 2915 | #define zig_bitSizeOf_repr_f32 32 | |
| 2916 | typedef zig_repr_f32 zig_f32; | |
| 3030 | #define zig_repr_f32 u32 | |
| 3031 | ypedef uint32_t zig_f32; | |
| 2917 | 3032 | #define zig_make_f32(fp, repr) repr |
| 2918 | 3033 | #undef zig_make_special_f32 |
| 2919 | 3034 | #define zig_make_special_f32(sign, name, arg, repr) repr |
| ... | ... | @@ -2922,20 +3037,12 @@ typedef zig_repr_f32 zig_f32; |
| 2922 | 3037 | #endif |
| 2923 | 3038 | |
| 2924 | 3039 | #define zig_has_f64 1 |
| 2925 | #define zig_bitSizeOf_f64 64 | |
| 2926 | typedef uint64_t zig_repr_f64; | |
| 2927 | 3040 | #define zig_libc_name_f64(name) name |
| 2928 | 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 | 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 | 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 | 3046 | #if FLT_MANT_DIG == 53 |
| 2940 | 3047 | typedef float zig_f64; |
| 2941 | 3048 | #define zig_make_f64(fp, repr) fp##f |
| ... | ... | @@ -2943,10 +3050,6 @@ typedef float zig_f64; |
| 2943 | 3050 | typedef double zig_f64; |
| 2944 | 3051 | #define zig_make_f64(fp, repr) fp |
| 2945 | 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 | 3053 | typedef long double zig_f64; |
| 2951 | 3054 | #define zig_make_f64(fp, repr) fp##l |
| 2952 | 3055 | #elif FLT64_MANT_DIG == 53 |
| ... | ... | @@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64; |
| 2958 | 3061 | #else |
| 2959 | 3062 | #undef zig_has_f64 |
| 2960 | 3063 | #define zig_has_f64 0 |
| 2961 | #define zig_bitSizeOf_repr_f64 64 | |
| 2962 | typedef zig_repr_f64 zig_f64; | |
| 3064 | #define zig_repr_f64 u64 | |
| 3065 | typedef uint64_t zig_f64; | |
| 2963 | 3066 | #define zig_make_f64(fp, repr) repr |
| 2964 | 3067 | #undef zig_make_special_f64 |
| 2965 | 3068 | #define zig_make_special_f64(sign, name, arg, repr) repr |
| ... | ... | @@ -2968,8 +3071,6 @@ typedef zig_repr_f64 zig_f64; |
| 2968 | 3071 | #endif |
| 2969 | 3072 | |
| 2970 | 3073 | #define zig_has_f80 1 |
| 2971 | #define zig_bitSizeOf_f80 80 | |
| 2972 | typedef zig_u128 zig_repr_f80; | |
| 2973 | 3074 | #define zig_libc_name_f80(name) __##name##x |
| 2974 | 3075 | #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) |
| 2975 | 3076 | #if FLT_MANT_DIG == 64 |
| ... | ... | @@ -2979,10 +3080,6 @@ typedef float zig_f80; |
| 2979 | 3080 | typedef double zig_f80; |
| 2980 | 3081 | #define zig_make_f80(fp, repr) fp |
| 2981 | 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 | 3083 | typedef long double zig_f80; |
| 2987 | 3084 | #define zig_make_f80(fp, repr) fp##l |
| 2988 | 3085 | #elif FLT80_MANT_DIG == 64 |
| ... | ... | @@ -2997,8 +3094,8 @@ typedef __float80 zig_f80; |
| 2997 | 3094 | #else |
| 2998 | 3095 | #undef zig_has_f80 |
| 2999 | 3096 | #define zig_has_f80 0 |
| 3000 | #define zig_bitSizeOf_repr_f80 128 | |
| 3001 | typedef zig_repr_f80 zig_f80; | |
| 3097 | #define zig_repr_f80 u128 | |
| 3098 | typedef zig_u128 zig_f80; | |
| 3002 | 3099 | #define zig_make_f80(fp, repr) repr |
| 3003 | 3100 | #undef zig_make_special_f80 |
| 3004 | 3101 | #define zig_make_special_f80(sign, name, arg, repr) repr |
| ... | ... | @@ -3007,8 +3104,6 @@ typedef zig_repr_f80 zig_f80; |
| 3007 | 3104 | #endif |
| 3008 | 3105 | |
| 3009 | 3106 | #define zig_has_f128 1 |
| 3010 | #define zig_bitSizeOf_f128 128 | |
| 3011 | typedef zig_u128 zig_repr_f128; | |
| 3012 | 3107 | #define zig_libc_name_f128(name) name##q |
| 3013 | 3108 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) |
| 3014 | 3109 | #if FLT_MANT_DIG == 113 |
| ... | ... | @@ -3018,10 +3113,6 @@ typedef float zig_f128; |
| 3018 | 3113 | typedef double zig_f128; |
| 3019 | 3114 | #define zig_make_f128(fp, repr) fp |
| 3020 | 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 | 3116 | typedef long double zig_f128; |
| 3026 | 3117 | #define zig_make_f128(fp, repr) fp##l |
| 3027 | 3118 | #elif FLT128_MANT_DIG == 113 |
| ... | ... | @@ -3038,50 +3129,49 @@ typedef __float128 zig_f128; |
| 3038 | 3129 | #else |
| 3039 | 3130 | #undef zig_has_f128 |
| 3040 | 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 | 3132 | #undef zig_make_special_f128 |
| 3045 | #define zig_make_special_f128(sign, name, arg, repr) repr | |
| 3046 | 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 | 3149 | #define zig_init_special_f128(sign, name, arg, repr) repr |
| 3048 | 3150 | #endif |
| 3151 | #endif | |
| 3049 | 3152 | |
| 3050 | #ifdef zig_bitSizeOf_c_longdouble | |
| 3051 | ||
| 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 | |
| 3153 | #if !_MSC_VER && defined(ZIG_TARGET_ABI_MSVC) | |
| 3154 | /* Emulate msvc abi on a gnu compiler */ | |
| 3056 | 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 | 3159 | #else |
| 3160 | /* Target and compiler abi match */ | |
| 3059 | 3161 | typedef long double zig_c_longdouble; |
| 3060 | 3162 | #endif |
| 3061 | 3163 | |
| 3062 | #else /* zig_bitSizeOf_c_longdouble */ | |
| 3063 | ||
| 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) { \ | |
| 3164 | #define zig_bitCast_float(Type, ReprType) \ | |
| 3165 | static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \ | |
| 3074 | 3166 | zig_##Type result; \ |
| 3075 | 3167 | memcpy(&result, &repr, sizeof(result)); \ |
| 3076 | 3168 | return result; \ |
| 3077 | 3169 | } |
| 3078 | ||
| 3079 | zig_float_from_repr(f16) | |
| 3080 | zig_float_from_repr(f32) | |
| 3081 | zig_float_from_repr(f64) | |
| 3082 | zig_float_from_repr(f80) | |
| 3083 | zig_float_from_repr(f128) | |
| 3084 | #endif | |
| 3170 | zig_bitCast_float(f16, uint16_t) | |
| 3171 | zig_bitCast_float(f32, uint32_t) | |
| 3172 | zig_bitCast_float(f64, uint64_t) | |
| 3173 | zig_bitCast_float(f80, zig_u128) | |
| 3174 | zig_bitCast_float(f128, zig_u128) | |
| 3085 | 3175 | |
| 3086 | 3176 | #define zig_cast_f16 (zig_f16) |
| 3087 | 3177 | #define zig_cast_f32 (zig_f32) |
| ... | ... | @@ -3095,44 +3185,53 @@ zig_float_from_repr(f128) |
| 3095 | 3185 | #define zig_cast_f128 (zig_f128) |
| 3096 | 3186 | #endif |
| 3097 | 3187 | |
| 3098 | #define zig_convert_builtin(ResType, operation, ArgType, version) \ | |
| 3099 | zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | |
| 3100 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType); | |
| 3101 | zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f32, 2) | |
| 3102 | zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f64, 2) | |
| 3103 | zig_convert_builtin(zig_f16, trunc, zig_f80, 2) | |
| 3104 | zig_convert_builtin(zig_f16, trunc, zig_f128, 2) | |
| 3105 | zig_convert_builtin(zig_f32, extend, zig_compiler_rt_f16, 2) | |
| 3106 | zig_convert_builtin(zig_f32, trunc, zig_f64, 2) | |
| 3107 | zig_convert_builtin(zig_f32, trunc, zig_f80, 2) | |
| 3108 | zig_convert_builtin(zig_f32, trunc, zig_f128, 2) | |
| 3109 | zig_convert_builtin(zig_f64, extend, zig_compiler_rt_f16, 2) | |
| 3110 | zig_convert_builtin(zig_f64, extend, zig_f32, 2) | |
| 3111 | zig_convert_builtin(zig_f64, trunc, zig_f80, 2) | |
| 3112 | zig_convert_builtin(zig_f64, trunc, zig_f128, 2) | |
| 3113 | zig_convert_builtin(zig_f80, extend, zig_f16, 2) | |
| 3114 | zig_convert_builtin(zig_f80, extend, zig_f32, 2) | |
| 3115 | zig_convert_builtin(zig_f80, extend, zig_f64, 2) | |
| 3116 | zig_convert_builtin(zig_f80, trunc, zig_f128, 2) | |
| 3117 | zig_convert_builtin(zig_f128, extend, zig_f16, 2) | |
| 3118 | zig_convert_builtin(zig_f128, extend, zig_f32, 2) | |
| 3119 | zig_convert_builtin(zig_f128, extend, zig_f64, 2) | |
| 3120 | zig_convert_builtin(zig_f128, extend, zig_f80, 2) | |
| 3121 | ||
| 3122 | #define zig_float_negate_builtin_0(w) \ | |
| 3123 | static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \ | |
| 3124 | return zig_expand_concat(zig_xor_u, zig_bitSizeOf_repr_f##w)( \ | |
| 3125 | arg, \ | |
| 3126 | zig_expand_concat(zig_shl_u, zig_bitSizeOf_repr_f##w)( \ | |
| 3127 | zig_expand_concat(zig_make_small_u, zig_bitSizeOf_repr_f##w)(1), \ | |
| 3128 | UINT8_C(w - 1) \ | |
| 3129 | ) \ | |
| 3130 | ); \ | |
| 3131 | } | |
| 3132 | #define zig_float_negate_builtin_1(w) \ | |
| 3188 | #define zig_convert_builtin(ExternResType, ResType, operation, ExternArgType, ArgType, version) \ | |
| 3189 | zig_extern ExternResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | |
| 3190 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ExternArgType); \ | |
| 3191 | static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ | |
| 3192 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ | |
| 3193 | ResType res; \ | |
| 3194 | ExternResType extern_res; \ | |
| 3195 | ExternArgType extern_arg; \ | |
| 3196 | memcpy(&extern_arg, &arg, sizeof(extern_arg)); \ | |
| 3197 | extern_res = zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | |
| 3198 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(extern_arg); \ | |
| 3199 | memcpy(&res, &extern_res, sizeof(res)); \ | |
| 3200 | return extern_res; \ | |
| 3201 | } | |
| 3202 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2) | |
| 3203 | zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2) | |
| 3204 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2) | |
| 3205 | zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2) | |
| 3206 | zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2) | |
| 3207 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2) | |
| 3208 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2) | |
| 3209 | zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2) | |
| 3210 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2) | |
| 3211 | zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2) | |
| 3212 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2) | |
| 3213 | zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2) | |
| 3214 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2) | |
| 3215 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2) | |
| 3216 | zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2) | |
| 3217 | zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2) | |
| 3218 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2) | |
| 3219 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2) | |
| 3220 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2) | |
| 3221 | zig_convert_builtin(zig_f128, zig_f128, extend, zig_f80, zig_f80, 2) | |
| 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 | 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 | 3236 | #define zig_float_less_builtin_0(Type, operation) \ |
| 3138 | 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 | 3263 | } |
| 3165 | 3264 | |
| 3166 | 3265 | #define zig_float_builtins(w) \ |
| 3167 | zig_convert_builtin( int32_t, fix, zig_f##w, ) \ | |
| 3168 | zig_convert_builtin(uint32_t, fixuns, zig_f##w, ) \ | |
| 3169 | zig_convert_builtin( int64_t, fix, zig_f##w, ) \ | |
| 3170 | zig_convert_builtin(uint64_t, fixuns, zig_f##w, ) \ | |
| 3171 | zig_convert_builtin(zig_i128, fix, zig_f##w, ) \ | |
| 3172 | zig_convert_builtin(zig_u128, fixuns, zig_f##w, ) \ | |
| 3173 | zig_convert_builtin(zig_f##w, float, int32_t, ) \ | |
| 3174 | zig_convert_builtin(zig_f##w, floatun, uint32_t, ) \ | |
| 3175 | zig_convert_builtin(zig_f##w, float, int64_t, ) \ | |
| 3176 | zig_convert_builtin(zig_f##w, floatun, uint64_t, ) \ | |
| 3177 | zig_convert_builtin(zig_f##w, float, zig_i128, ) \ | |
| 3178 | zig_convert_builtin(zig_f##w, floatun, zig_u128, ) \ | |
| 3179 | zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w) \ | |
| 3266 | zig_convert_builtin( int32_t, int32_t, fix, zig_f##w, zig_f##w, ) \ | |
| 3267 | zig_convert_builtin(uint32_t, uint32_t, fixuns, zig_f##w, zig_f##w, ) \ | |
| 3268 | zig_convert_builtin( int64_t, int64_t, fix, zig_f##w, zig_f##w, ) \ | |
| 3269 | zig_convert_builtin(uint64_t, uint64_t, fixuns, zig_f##w, zig_f##w, ) \ | |
| 3270 | zig_convert_builtin(zig_i128, zig_i128, fix, zig_f##w, zig_f##w, ) \ | |
| 3271 | zig_convert_builtin(zig_u128, zig_u128, fixuns, zig_f##w, zig_f##w, ) \ | |
| 3272 | zig_convert_builtin(zig_f##w, zig_f##w, float, int32_t, int32_t, ) \ | |
| 3273 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint32_t, uint32_t, ) \ | |
| 3274 | zig_convert_builtin(zig_f##w, zig_f##w, float, int64_t, int64_t, ) \ | |
| 3275 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, uint64_t, uint64_t, ) \ | |
| 3276 | zig_convert_builtin(zig_f##w, zig_f##w, float, zig_i128, zig_i128, ) \ | |
| 3277 | zig_convert_builtin(zig_f##w, zig_f##w, floatun, zig_u128, zig_u128, ) \ | |
| 3180 | 3278 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ |
| 3181 | 3279 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \ |
| 3182 | 3280 | zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \ |
| ... | ... | @@ -3224,9 +3322,238 @@ zig_float_builtins(64) |
| 3224 | 3322 | zig_float_builtins(80) |
| 3225 | 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 | 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 | 3558 | #define zig_msvc_atomics(ZigType, Type, SigType, suffix) \ |
| 3232 | 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 | 3643 | zig_msvc_atomics(i64, int64_t, __int64, 64) |
| 3317 | 3644 | #endif |
| 3318 | 3645 | |
| 3319 | #define zig_msvc_flt_atomics(Type, ReprType, suffix) \ | |
| 3646 | #define zig_msvc_flt_atomics(Type, SigType, suffix) \ | |
| 3320 | 3647 | static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \ |
| 3321 | ReprType exchange; \ | |
| 3322 | ReprType comparand; \ | |
| 3323 | ReprType initial; \ | |
| 3648 | SigType exchange; \ | |
| 3649 | SigType comparand; \ | |
| 3650 | SigType initial; \ | |
| 3324 | 3651 | bool success; \ |
| 3325 | 3652 | memcpy(&comparand, expected, sizeof(comparand)); \ |
| 3326 | 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 | 3655 | success = initial == comparand; \ |
| 3329 | 3656 | if (!success) memcpy(expected, &initial, sizeof(*expected)); \ |
| 3330 | 3657 | return success; \ |
| 3331 | 3658 | } \ |
| 3332 | static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \ | |
| 3333 | ReprType repr; \ | |
| 3334 | ReprType initial; \ | |
| 3659 | static inline void zig_msvc_atomic_store_##Type(zig_##Type volatile* obj, zig_##Type arg) { \ | |
| 3660 | SigType value; \ | |
| 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 | 3665 | zig_##Type result; \ |
| 3336 | memcpy(&repr, &value, sizeof(repr)); \ | |
| 3337 | initial = _InterlockedExchange##suffix((ReprType volatile*)obj, repr); \ | |
| 3666 | SigType initial = _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \ | |
| 3338 | 3667 | memcpy(&result, &initial, sizeof(result)); \ |
| 3339 | 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 | 3670 | zig_msvc_flt_atomics(f32, long, ) |
| 3365 | 3671 | #if _M_X64 |
| 3366 | 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 | 3727 | static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) { |
| 3422 | 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 | 3730 | #endif /* _M_IX86 */ |
| 3461 | 3731 | |
| 3462 | 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 | 401 | } |
| 402 | 402 | |
| 403 | 403 | test "explicit cast from integer to error type" { |
| 404 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 405 | 404 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 406 | 405 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 407 | 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 | 1649 | }; |
| 1650 | 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 | 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 | 475 | test "using @ptrCast on function pointers" { |
| 459 | 476 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 460 | 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 | 486 | } |
| 487 | 487 | |
| 488 | 488 | test "Type.Fn" { |
| 489 | if (true) { | |
| 490 | // https://github.com/ziglang/zig/issues/12360 | |
| 491 | return error.SkipZigTest; | |
| 492 | } | |
| 489 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | |
| 490 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 491 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 493 | 492 | |
| 494 | 493 | const some_opaque = opaque {}; |
| 495 | 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 | 29 | // |
| 30 | 30 | // :9:1: error: union initializer must initialize one field |
| 31 | 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 | 33 | // :14:31: note: additional initializer here |
| 34 | 34 | // :1:12: note: union declared here |
| 35 | 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 | 37 | // :22:31: note: additional initializer here |
| 38 | 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 | 21 | // backend=stage2 |
| 22 | 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 | 25 | // :9:24: error: arrays must be passed by reference to variadic function |
| 26 | 26 | // :13:24: error: cannot pass 'u48' to variadic function |
| 27 | 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 | 1040 | }); |
| 1041 | 1041 | compile_c.addIncludePath("lib"); // for zig.h |
| 1042 | 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 | 1049 | if (test_target.link_libc == false) { |
| 1044 | 1050 | compile_c.subsystem = .Console; |
| 1045 | 1051 | compile_c.linkSystemLibrary("kernel32"); |
test/translate_c.zig+6| ... | ... | @@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3956 | 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 | } |