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

Merge branch 'master' into autodoc-pkg-mod


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

doc/langref.html.in+65-15
......@@ -1422,7 +1422,8 @@ fn foo() i32 {
14221422
14231423 {#header_open|Thread Local Variables#}
14241424 <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>
14261427 {#code_begin|test|test_thread_local_variables#}
14271428const std = @import("std");
14281429const assert = std.debug.assert;
......@@ -4278,7 +4279,7 @@ const expectError = std.testing.expectError;
42784279fn isFieldOptional(comptime T: type, field_index: usize) !bool {
42794280 const fields = @typeInfo(T).Struct.fields;
42804281 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
42824283 // unique comptime-known value each time.
42834284 inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .Optional,
42844285 else => return error.IndexOutOfBounds,
......@@ -4667,6 +4668,29 @@ test "for basics" {
46674668 sum2 += @intCast(i32, i);
46684669 }
46694670 try expect(sum2 == 10);
4671
4672 // To iterate over consecutive integers, use the range syntax.
4673 // Unbounded range is always a compile error.
4674 var sum3 : usize = 0;
4675 for (0..5) |i| {
4676 sum3 += i;
4677 }
4678 try expect(sum3 == 10);
4679}
4680
4681test "multi object for" {
4682 const items = [_]usize{ 1, 2, 3 };
4683 const items2 = [_]usize{ 4, 5, 6 };
4684 var count: usize = 0;
4685
4686 // Iterate over multiple objects.
4687 // All lengths must be equal at the start of the loop, otherwise detectable
4688 // illegal behavior occurs.
4689 for (items, items2) |i, j| {
4690 count += i + j;
4691 }
4692
4693 try expect(count == 21);
46704694}
46714695
46724696test "for reference" {
......@@ -4710,8 +4734,8 @@ const expect = std.testing.expect;
47104734
47114735test "nested break" {
47124736 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) |_| {
47154739 count += 1;
47164740 break :outer;
47174741 }
......@@ -4721,8 +4745,8 @@ test "nested break" {
47214745
47224746test "nested continue" {
47234747 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) |_| {
47264750 count += 1;
47274751 continue :outer;
47284752 }
......@@ -8017,7 +8041,7 @@ pub const CallModifier = enum {
80178041 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
80188042 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>
80198043 <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".
80218045 </p>
80228046 <p>
80238047 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,
......@@ -8167,7 +8191,7 @@ test "main" {
81678191 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
81688192 <p>{#syntax#}operand{#endsyntax#} may be an {#link|integer|Integers#} or {#link|vector|Vectors#}.</p>
81698193 <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".
81718195 </p>
81728196 <p>
81738197 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,
......@@ -8553,16 +8577,27 @@ test "@hasDecl" {
85538577 </p>
85548578 <ul>
85558579 <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
85578581 The command <code>zig build-exe --show-builtin</code> outputs the source to stdout for reference.
85588582 </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.
85618585 </li>
85628586 </ul>
85638587 {#see_also|Compile Variables|@embedFile#}
85648588 {#header_close#}
85658589
8590 {#header_open|@inComptime#}
8591 <pre>{#syntax#}@inComptime() bool{#endsyntax#}</pre>
8592 <p>
8593 Returns whether the builtin was run in a {#syntax#}comptime{#endsyntax#} context. The result is a compile-time constant.
8594 </p>
8595 <p>
8596 This can be used to provide alternative, comptime-friendly implementations of functions. It should not be used, for instance, to exclude certain functions from being evaluated at comptime.
8597 </p>
8598 {#see_also|comptime#}
8599 {#header_close#}
8600
85668601 {#header_open|@intCast#}
85678602 <pre>{#syntax#}@intCast(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre>
85688603 <p>
......@@ -8780,7 +8815,9 @@ test "@wasmMemoryGrow" {
87808815 <pre>{#syntax#}@popCount(operand: anytype) anytype{#endsyntax#}</pre>
87818816 <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type.</p>
87828817 <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>
87848821 <p>
87858822 If {#syntax#}operand{#endsyntax#} is a {#link|comptime#}-known integer,
87868823 the return type is {#syntax#}comptime_int{#endsyntax#}.
......@@ -8812,6 +8849,8 @@ test "@wasmMemoryGrow" {
88128849pub const PrefetchOptions = struct {
88138850 /// Whether the prefetch should prepare for a read or a write.
88148851 rw: Rw = .read,
8852 /// The data's locality in an inclusive range from 0 to 3.
8853 ///
88158854 /// 0 means no temporal locality. That is, the data can be immediately
88168855 /// dropped from the cache after it is accessed.
88178856 ///
......@@ -8821,12 +8860,12 @@ pub const PrefetchOptions = struct {
88218860 /// The cache that the prefetch should be preformed on.
88228861 cache: Cache = .data,
88238862
8824 pub const Rw = enum {
8863 pub const Rw = enum(u1) {
88258864 read,
88268865 write,
88278866 };
88288867
8829 pub const Cache = enum {
8868 pub const Cache = enum(u1) {
88308869 instruction,
88318870 data,
88328871 };
......@@ -10948,7 +10987,7 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke
1094810987 </p>
1094910988 <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>
1095010989 <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>
1095210991 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.
1095310992 When a C pointer is coerced to a non-optional pointer, safety-checked
1095410993 {#link|Undefined Behavior#} occurs if the address is 0.
......@@ -11966,6 +12005,17 @@ fn readU32Be() u32 {}
1196612005 </ul>
1196712006 </td>
1196812007 </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>
1196912019 <tr>
1197012020 <th scope="row">
1197112021 <pre>{#syntax#}nosuspend{#endsyntax#}</pre>
lib/std/Build/Cache.zig+1-1
......@@ -184,7 +184,7 @@ pub const File = struct {
184184pub const HashHelper = struct {
185185 hasher: Hasher = hasher_init,
186186
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.
188188 pub fn addBytes(hh: *HashHelper, bytes: []const u8) void {
189189 hh.hasher.update(mem.asBytes(&bytes.len));
190190 hh.hasher.update(bytes);
lib/std/RingBuffer.zig+1-1
......@@ -1,7 +1,7 @@
11//! This ring buffer stores read and write indices while being able to utilise
22//! the full backing slice by incrementing the indices modulo twice the slice's
33//! 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
55//! looking at the difference between the read and write indices without adding
66//! an extra boolean flag or having to reserve a slot in the buffer.
77//!
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>.
22//! Does not do perfect grammar and character class checking, but should be robust against URIs in the wild.
33
44const Uri = @This();
lib/std/array_list.zig+2
......@@ -221,6 +221,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
221221 /// Asserts the array has at least one item.
222222 /// Invalidates pointers to end of list.
223223 /// This operation is O(N).
224 /// This preserves item order. Use `swapRemove` if order preservation is not important.
224225 pub fn orderedRemove(self: *Self, i: usize) T {
225226 const newlen = self.items.len - 1;
226227 if (newlen == i) return self.pop();
......@@ -235,6 +236,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
235236 /// Removes the element at the specified index and returns it.
236237 /// The empty slot is filled from the end of the list.
237238 /// This operation is O(1).
239 /// This may not preserve item order. Use `orderedRemove` if you need to preserve order.
238240 pub fn swapRemove(self: *Self, i: usize) T {
239241 if (self.items.len - 1 == i) return self.pop();
240242
lib/std/bit_set.zig+3-2
......@@ -35,9 +35,10 @@ const assert = std.debug.assert;
3535const Allocator = std.mem.Allocator;
3636
3737/// 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,
3941/// can be copied by value, and does not require deinitialization.
40/// Both possible implementations fulfill the same interface.
4142pub fn StaticBitSet(comptime size: usize) type {
4243 if (size <= @bitSizeOf(usize)) {
4344 return IntegerBitSet(size);
lib/std/builtin.zig+27
......@@ -144,22 +144,47 @@ pub const Mode = OptimizeMode;
144144/// This data structure is used by the Zig language code generation and
145145/// therefore must be kept in sync with the compiler implementation.
146146pub 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.
147149 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.
148153 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.
149157 Naked,
158 /// Functions with this calling convention are called asynchronously,
159 /// as if called as `async function()`.
150160 Async,
161 /// Functions with this calling convention are inlined at all call sites.
151162 Inline,
163 /// x86-only.
152164 Interrupt,
153165 Signal,
166 /// x86-only.
154167 Stdcall,
168 /// x86-only.
155169 Fastcall,
170 /// x86-only.
156171 Vectorcall,
172 /// x86-only.
157173 Thiscall,
174 /// ARM Procedure Call Standard (obsolete)
175 /// ARM-only.
158176 APCS,
177 /// ARM Architecture Procedure Call Standard (current standard)
178 /// ARM-only.
159179 AAPCS,
180 /// ARM Architecture Procedure Call Standard Vector Floating-Point
181 /// ARM-only.
160182 AAPCSVFP,
183 /// x86-64-only.
161184 SysV,
185 /// x86-64-only.
162186 Win64,
187 /// AMD GPU, NVPTX, or SPIR-V kernel
163188 Kernel,
164189};
165190
......@@ -716,6 +741,8 @@ pub const VaList = switch (builtin.cpu.arch) {
716741pub const PrefetchOptions = struct {
717742 /// Whether the prefetch should prepare for a read or a write.
718743 rw: Rw = .read,
744 /// The data's locality in an inclusive range from 0 to 3.
745 ///
719746 /// 0 means no temporal locality. That is, the data can be immediately
720747 /// dropped from the cache after it is accessed.
721748 ///
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
38463846pub extern "c" fn os_signpost_interval_end(log: os_log_t, signpos: os_signpost_id_t, func: [*]const u8, ...) void;
38473847pub extern "c" fn os_signpost_id_make_with_pointer(log: os_log_t, ptr: ?*anyopaque) os_signpost_id_t;
38483848pub extern "c" fn os_signpost_enabled(log: os_log_t) bool;
3849
3850pub extern "c" fn proc_listpids(tpe: u32, tinfo: u32, buffer: ?*anyopaque, buffersize: c_int) c_int;
3851pub extern "c" fn proc_listallpids(buffer: ?*anyopaque, buffersize: c_int) c_int;
3852pub extern "c" fn proc_listpgrppids(pgrpid: pid_t, buffer: ?*anyopaque, buffersize: c_int) c_int;
3853pub extern "c" fn proc_listchildpids(ppid: pid_t, buffer: ?*anyopaque, buffersize: c_int) c_int;
3854pub extern "c" fn proc_pidinfo(pid: c_int, flavor: c_int, arg: u64, buffer: ?*anyopaque, buffersize: c_int) c_int;
3855pub extern "c" fn proc_name(pid: c_int, buffer: ?*anyopaque, buffersize: u32) c_int;
3856pub extern "c" fn proc_pidpath(pid: c_int, buffer: ?*anyopaque, buffersize: u32) c_int;
lib/std/c/dragonfly.zig+17
......@@ -1143,3 +1143,20 @@ pub const POLL = struct {
11431143 pub const HUP = 0x0010;
11441144 pub const NVAL = 0x0020;
11451145};
1146
1147pub const SIGEV = struct {
1148 pub const NONE = 0;
1149 pub const SIGNAL = 1;
1150 pub const THREAD = 2;
1151};
1152
1153pub const sigevent = extern struct {
1154 sigev_notify: c_int,
1155 __sigev_u: extern union {
1156 __sigev_signo: c_int,
1157 __sigev_notify_kqueue: c_int,
1158 __sigev_notify_attributes: ?*pthread_attr_t,
1159 },
1160 sigev_value: sigval,
1161 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1162};
lib/std/c/freebsd.zig+91-5
......@@ -29,6 +29,8 @@ pub const CPU_WHICH_TIDPID: cpuwhich_t = 8;
2929extern "c" fn __error() *c_int;
3030pub const _errno = __error;
3131
32pub extern "c" var malloc_options: [*:0]const u8;
33
3234pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
3335pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
3436pub 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;
4244
4345pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
4446pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;
47pub extern "c" fn reallocf(?*anyopaque, usize) ?*anyopaque;
4548
4649pub extern "c" fn getpid() pid_t;
4750
......@@ -50,6 +53,9 @@ pub extern "c" fn kinfo_getvmmap(pid: pid_t, cntp: *c_int) ?[*]kinfo_vmentry;
5053
5154pub extern "c" fn cpuset_getaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *cpuset_t) c_int;
5255pub extern "c" fn cpuset_setaffinity(level: cpulevel_t, which: cpuwhich_t, id: id_t, setsize: usize, mask: *const cpuset_t) c_int;
56pub extern "c" fn sched_getaffinity(pid: pid_t, cpusetsz: usize, cpuset: *cpuset_t) c_int;
57pub extern "c" fn sched_setaffinity(pid: pid_t, cpusetsz: usize, cpuset: *const cpuset_t) c_int;
58pub extern "c" fn sched_getcpu() c_int;
5359
5460pub const sf_hdtr = extern struct {
5561 headers: [*]const iovec_const,
......@@ -1102,6 +1108,11 @@ pub const DT = struct {
11021108 pub const WHT = 14;
11031109};
11041110
1111pub const accept_filter = extern struct {
1112 af_name: [16]u8,
1113 af_args: [240]u8,
1114};
1115
11051116/// add event to kq (implies enable)
11061117pub const EV_ADD = 0x0001;
11071118
......@@ -1383,15 +1394,47 @@ pub const mcontext_t = switch (builtin.cpu.arch) {
13831394 rflags: u64,
13841395 rsp: u64,
13851396 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),
13901401 fsbase: u64,
13911402 gsbase: u64,
13921403 xfpustate: u64,
13931404 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,
13951438 },
13961439 .aarch64 => extern struct {
13971440 gpregs: extern struct {
......@@ -2205,3 +2248,46 @@ pub const shm_largeconf = extern struct {
22052248pub extern "c" fn shm_create_largepage(path: [*:0]const u8, flags: c_int, psind: c_int, alloc_policy: c_int, mode: mode_t) c_int;
22062249
22072250pub extern "c" fn elf_aux_info(aux: c_int, buf: ?*anyopaque, buflen: c_int) c_int;
2251
2252pub const lwpid = i32;
2253
2254pub const SIGEV = struct {
2255 pub const NONE = 0;
2256 pub const SIGNAL = 1;
2257 pub const THREAD = 2;
2258 pub const KEVENT = 3;
2259 pub const THREAD_ID = 4;
2260};
2261
2262pub const sigevent = extern struct {
2263 sigev_notify: c_int,
2264 sigev_signo: c_int,
2265 sigev_value: sigval,
2266 _sigev_un: extern union {
2267 _threadid: lwpid,
2268 _sigev_thread: extern struct {
2269 _function: ?*const fn (sigval) callconv(.C) void,
2270 _attribute: ?**pthread_attr_t,
2271 },
2272 _kevent_flags: c_ushort,
2273 __spare__: [8]c_long,
2274 },
2275};
2276
2277pub const MIN = struct {
2278 pub const INCORE = 0x1;
2279 pub const REFERENCED = 0x2;
2280 pub const MODIFIED = 0x4;
2281 pub const REFERENCED_OTHER = 0x8;
2282 pub const MODIFIED_OTHER = 0x10;
2283 pub const SUPER = 0x60;
2284 pub fn PSIND(i: u32) u32 {
2285 return (i << 5) & SUPER;
2286 }
2287};
2288
2289pub extern "c" fn mincore(
2290 addr: *align(std.mem.page_size) const anyopaque,
2291 length: usize,
2292 vec: [*]u8,
2293) c_int;
lib/std/c/haiku.zig+24-1
......@@ -5,11 +5,15 @@ const maxInt = std.math.maxInt;
55const iovec = std.os.iovec;
66const iovec_const = std.os.iovec_const;
77
8const status_t = i32;
9
810extern "c" fn _errnop() *c_int;
911
1012pub const _errno = _errnop;
1113
12pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;
14pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) status_t;
15
16pub extern "c" fn find_path(codePointer: *const u8, baseDirectory: c_int, subPath: [*:0]const u8, pathBuffer: [*:0]u8, bufferSize: usize) status_t;
1317
1418pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;
1519
......@@ -1038,3 +1042,22 @@ pub const termios = extern struct {
10381042};
10391043
10401044pub const MSG_NOSIGNAL = 0x0800;
1045
1046pub const SIGEV = struct {
1047 pub const NONE = 0;
1048 pub const SIGNAL = 1;
1049 pub const THREAD = 2;
1050};
1051
1052pub const sigval = extern union {
1053 int: c_int,
1054 ptr: ?*anyopaque,
1055};
1056
1057pub const sigevent = extern struct {
1058 sigev_notify: c_int,
1059 sigev_signo: c_int,
1060 sigev_value: sigval,
1061 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1062 sigev_notify_attributes: ?*pthread_attr_t,
1063};
lib/std/c/netbsd.zig+19
......@@ -1633,3 +1633,22 @@ pub const POLL = struct {
16331633 pub const HUP = 0x0010;
16341634 pub const NVAL = 0x0020;
16351635};
1636
1637pub const SIGEV = struct {
1638 pub const NONE = 0;
1639 pub const SIGNAL = 1;
1640 pub const THREAD = 2;
1641};
1642
1643pub const sigval = extern union {
1644 int: c_int,
1645 ptr: ?*anyopaque,
1646};
1647
1648pub const sigevent = extern struct {
1649 sigev_notify: c_int,
1650 sigev_signo: c_int,
1651 sigev_value: sigval,
1652 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1653 sigev_notify_attributes: ?*pthread_attr_t,
1654};
lib/std/c/solaris.zig+19
......@@ -1927,3 +1927,22 @@ pub fn IOW(io_type: u8, nr: u8, comptime IOT: type) i32 {
19271927pub fn IOWR(io_type: u8, nr: u8, comptime IOT: type) i32 {
19281928 return ioImpl(.read_write, io_type, nr, IOT);
19291929}
1930
1931pub const SIGEV = struct {
1932 pub const NONE = 0;
1933 pub const SIGNAL = 1;
1934 pub const THREAD = 2;
1935};
1936
1937pub const sigval = extern union {
1938 int: c_int,
1939 ptr: ?*anyopaque,
1940};
1941
1942pub const sigevent = extern struct {
1943 sigev_notify: c_int,
1944 sigev_signo: c_int,
1945 sigev_value: sigval,
1946 sigev_notify_function: ?*const fn (sigval) callconv(.C) void,
1947 sigev_notify_attributes: ?*pthread_attr_t,
1948};
lib/std/compress/zstandard.zig+1-1
......@@ -10,7 +10,7 @@ pub const decompress = @import("zstandard/decompress.zig");
1010
1111pub const DecompressStreamOptions = struct {
1212 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
1414};
1515
1616pub fn DecompressStream(
lib/std/compress/zstandard/decode/fse.zig+1-1
......@@ -21,7 +21,7 @@ pub fn decodeFseTable(
2121 var accumulated_probability: u16 = 0;
2222
2323 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,
2525 // but power of two (remaining probabilities + 1) need max bits set to 1 more.
2626 const max_bits = std.math.log2_int(u16, total_probability - accumulated_probability + 1) + 1;
2727 const small = try bit_reader.readBitsNoEof(u16, max_bits - 1);
lib/std/crypto/sha2.zig+1-7
......@@ -71,12 +71,6 @@ const Sha256Params = Sha2Params32{
7171
7272const v4u32 = @Vector(4, u32);
7373
74// TODO: Remove once https://github.com/ziglang/zig/issues/868 is resolved.
75fn isComptime() bool {
76 var a: u8 = 0;
77 return @typeInfo(@TypeOf(.{a})).Struct.fields[0].is_comptime;
78}
79
8074/// SHA-224
8175pub const Sha224 = Sha2x32(Sha224Params);
8276
......@@ -203,7 +197,7 @@ fn Sha2x32(comptime params: Sha2Params32) type {
203197 s[i] = mem.readIntBig(u32, mem.asBytes(elem));
204198 }
205199
206 if (!isComptime()) {
200 if (!@inComptime()) {
207201 switch (builtin.cpu.arch) {
208202 .aarch64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) {
209203 var x: v4u32 = d.s[0..4].*;
lib/std/debug.zig+2
......@@ -651,6 +651,8 @@ pub fn writeCurrentStackTraceWindows(
651651 }
652652}
653653
654/// Provides simple functionality for manipulating the terminal in some way,
655/// for debugging purposes, such as coloring text, etc.
654656pub const TTY = struct {
655657 pub const Color = enum {
656658 Red,
lib/std/elf.zig+88-5
......@@ -221,75 +221,138 @@ pub const DT_IA_64_NUM = 1;
221221
222222pub const DT_NIOS2_GP = 0x70000002;
223223
224/// Program header table entry unused
224225pub const PT_NULL = 0;
226/// Loadable program segment
225227pub const PT_LOAD = 1;
228/// Dynamic linking information
226229pub const PT_DYNAMIC = 2;
230/// Program interpreter
227231pub const PT_INTERP = 3;
232/// Auxiliary information
228233pub const PT_NOTE = 4;
234/// Reserved
229235pub const PT_SHLIB = 5;
236/// Entry for header table itself
230237pub const PT_PHDR = 6;
238/// Thread-local storage segment
231239pub const PT_TLS = 7;
240/// Number of defined types
232241pub const PT_NUM = 8;
242/// Start of OS-specific
233243pub const PT_LOOS = 0x60000000;
244/// GCC .eh_frame_hdr segment
234245pub const PT_GNU_EH_FRAME = 0x6474e550;
246/// Indicates stack executability
235247pub const PT_GNU_STACK = 0x6474e551;
248/// Read-only after relocation
236249pub const PT_GNU_RELRO = 0x6474e552;
237250pub const PT_LOSUNW = 0x6ffffffa;
251/// Sun specific segment
238252pub const PT_SUNWBSS = 0x6ffffffa;
253/// Stack segment
239254pub const PT_SUNWSTACK = 0x6ffffffb;
240255pub const PT_HISUNW = 0x6fffffff;
256/// End of OS-specific
241257pub const PT_HIOS = 0x6fffffff;
258/// Start of processor-specific
242259pub const PT_LOPROC = 0x70000000;
260/// End of processor-specific
243261pub const PT_HIPROC = 0x7fffffff;
244262
263/// Section header table entry unused
245264pub const SHT_NULL = 0;
265/// Program data
246266pub const SHT_PROGBITS = 1;
267/// Symbol table
247268pub const SHT_SYMTAB = 2;
269/// String table
248270pub const SHT_STRTAB = 3;
271/// Relocation entries with addends
249272pub const SHT_RELA = 4;
273/// Symbol hash table
250274pub const SHT_HASH = 5;
275/// Dynamic linking information
251276pub const SHT_DYNAMIC = 6;
277/// Notes
252278pub const SHT_NOTE = 7;
279/// Program space with no data (bss)
253280pub const SHT_NOBITS = 8;
281/// Relocation entries, no addends
254282pub const SHT_REL = 9;
283/// Reserved
255284pub const SHT_SHLIB = 10;
285/// Dynamic linker symbol table
256286pub const SHT_DYNSYM = 11;
287/// Array of constructors
257288pub const SHT_INIT_ARRAY = 14;
289/// Array of destructors
258290pub const SHT_FINI_ARRAY = 15;
291/// Array of pre-constructors
259292pub const SHT_PREINIT_ARRAY = 16;
293/// Section group
260294pub const SHT_GROUP = 17;
295/// Extended section indices
261296pub const SHT_SYMTAB_SHNDX = 18;
297/// Start of OS-specific
262298pub const SHT_LOOS = 0x60000000;
299/// End of OS-specific
263300pub const SHT_HIOS = 0x6fffffff;
301/// Start of processor-specific
264302pub const SHT_LOPROC = 0x70000000;
303/// End of processor-specific
265304pub const SHT_HIPROC = 0x7fffffff;
305/// Start of application-specific
266306pub const SHT_LOUSER = 0x80000000;
307/// End of application-specific
267308pub const SHT_HIUSER = 0xffffffff;
268309
310/// Local symbol
269311pub const STB_LOCAL = 0;
312/// Global symbol
270313pub const STB_GLOBAL = 1;
314/// Weak symbol
271315pub const STB_WEAK = 2;
316/// Number of defined types
272317pub const STB_NUM = 3;
318/// Start of OS-specific
273319pub const STB_LOOS = 10;
320/// Unique symbol
274321pub const STB_GNU_UNIQUE = 10;
322/// End of OS-specific
275323pub const STB_HIOS = 12;
324/// Start of processor-specific
276325pub const STB_LOPROC = 13;
326/// End of processor-specific
277327pub const STB_HIPROC = 15;
278328
279329pub const STB_MIPS_SPLIT_COMMON = 13;
280330
331/// Symbol type is unspecified
281332pub const STT_NOTYPE = 0;
333/// Symbol is a data object
282334pub const STT_OBJECT = 1;
335/// Symbol is a code object
283336pub const STT_FUNC = 2;
337/// Symbol associated with a section
284338pub const STT_SECTION = 3;
339/// Symbol's name is file name
285340pub const STT_FILE = 4;
341/// Symbol is a common data object
286342pub const STT_COMMON = 5;
343/// Symbol is thread-local data object
287344pub const STT_TLS = 6;
345/// Number of defined types
288346pub const STT_NUM = 7;
347/// Start of OS-specific
289348pub const STT_LOOS = 10;
349/// Symbol is indirect code object
290350pub const STT_GNU_IFUNC = 10;
351/// End of OS-specific
291352pub const STT_HIOS = 12;
353/// Start of processor-specific
292354pub const STT_LOPROC = 13;
355/// End of processor-specific
293356pub const STT_HIPROC = 15;
294357
295358pub const STT_SPARC_REGISTER = 13;
......@@ -656,6 +719,13 @@ pub const Elf32_Sym = extern struct {
656719 st_info: u8,
657720 st_other: u8,
658721 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 }
659729};
660730pub const Elf64_Sym = extern struct {
661731 st_name: Elf64_Word,
......@@ -664,6 +734,13 @@ pub const Elf64_Sym = extern struct {
664734 st_shndx: Elf64_Section,
665735 st_value: Elf64_Addr,
666736 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 }
667744};
668745pub const Elf32_Syminfo = extern struct {
669746 si_boundto: Elf32_Half,
......@@ -681,7 +758,7 @@ pub const Elf32_Rel = extern struct {
681758 return @truncate(u24, self.r_info >> 8);
682759 }
683760 pub inline fn r_type(self: @This()) u8 {
684 return @truncate(u8, self.r_info & 0xff);
761 return @truncate(u8, self.r_info);
685762 }
686763};
687764pub const Elf64_Rel = extern struct {
......@@ -692,7 +769,7 @@ pub const Elf64_Rel = extern struct {
692769 return @truncate(u32, self.r_info >> 32);
693770 }
694771 pub inline fn r_type(self: @This()) u32 {
695 return @truncate(u32, self.r_info & 0xffffffff);
772 return @truncate(u32, self.r_info);
696773 }
697774};
698775pub const Elf32_Rela = extern struct {
......@@ -704,7 +781,7 @@ pub const Elf32_Rela = extern struct {
704781 return @truncate(u24, self.r_info >> 8);
705782 }
706783 pub inline fn r_type(self: @This()) u8 {
707 return @truncate(u8, self.r_info & 0xff);
784 return @truncate(u8, self.r_info);
708785 }
709786};
710787pub const Elf64_Rela = extern struct {
......@@ -716,7 +793,7 @@ pub const Elf64_Rela = extern struct {
716793 return @truncate(u32, self.r_info >> 32);
717794 }
718795 pub inline fn r_type(self: @This()) u32 {
719 return @truncate(u32, self.r_info & 0xffffffff);
796 return @truncate(u32, self.r_info);
720797 }
721798};
722799pub const Elf32_Dyn = extern struct {
......@@ -1630,14 +1707,20 @@ pub const PF_MASKOS = 0x0ff00000;
16301707/// Bits for processor-specific semantics.
16311708pub const PF_MASKPROC = 0xf0000000;
16321709
1633// Special section indexes used in Elf{32,64}_Sym.
1710/// Undefined section
16341711pub const SHN_UNDEF = 0;
1712/// Start of reserved indices
16351713pub const SHN_LORESERVE = 0xff00;
1714/// Start of processor-specific
16361715pub const SHN_LOPROC = 0xff00;
1716/// End of processor-specific
16371717pub const SHN_HIPROC = 0xff1f;
16381718pub const SHN_LIVEPATCH = 0xff20;
1719/// Associated symbol is absolute
16391720pub const SHN_ABS = 0xfff1;
1721/// Associated symbol is common
16401722pub const SHN_COMMON = 0xfff2;
1723/// End of reserved indices
16411724pub const SHN_HIRESERVE = 0xffff;
16421725
16431726/// AMD x86-64 relocations.
lib/std/fmt.zig+2-9
......@@ -41,7 +41,7 @@ pub const FormatOptions = struct {
4141/// brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...}
4242/// - *specifier* is a type-dependent formatting option that determines how a type should formatted (see below)
4343/// - *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
4545/// - *width* is the total width of the field in characters
4646/// - *precision* specifies how many decimals a formatted number should have
4747///
......@@ -1428,8 +1428,7 @@ pub fn formatInt(
14281428 var a: MinInt = abs_value;
14291429 var index: usize = buf.len;
14301430
1431 // TODO isComptime here because of https://github.com/ziglang/zig/issues/13335.
1432 if (base == 10 and !isComptime()) {
1431 if (base == 10) {
14331432 while (a >= 100) : (a = @divTrunc(a, 100)) {
14341433 index -= 2;
14351434 buf[index..][0..2].* = digits2(@intCast(usize, a % 100));
......@@ -1469,12 +1468,6 @@ pub fn formatInt(
14691468 return formatBuf(buf[index..], options, writer);
14701469}
14711470
1472// TODO: Remove once https://github.com/ziglang/zig/issues/868 is resolved.
1473fn isComptime() bool {
1474 var a: u8 = 0;
1475 return @typeInfo(@TypeOf(.{a})).Struct.fields[0].is_comptime;
1476}
1477
14781471pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) usize {
14791472 var fbs = std.io.fixedBufferStream(out_buf);
14801473 formatInt(value, base, case, options, fbs.writer()) catch unreachable;
lib/std/fs.zig+13-2
......@@ -1236,6 +1236,7 @@ pub const Dir = struct {
12361236 .capable_io_mode = std.io.default_mode,
12371237 .intended_io_mode = flags.intended_io_mode,
12381238 };
1239 errdefer file.close();
12391240 var io: w.IO_STATUS_BLOCK = undefined;
12401241 const range_off: w.LARGE_INTEGER = 0;
12411242 const range_len: w.LARGE_INTEGER = 1;
......@@ -1396,6 +1397,7 @@ pub const Dir = struct {
13961397 .capable_io_mode = std.io.default_mode,
13971398 .intended_io_mode = flags.intended_io_mode,
13981399 };
1400 errdefer file.close();
13991401 var io: w.IO_STATUS_BLOCK = undefined;
14001402 const range_off: w.LARGE_INTEGER = 0;
14011403 const range_len: w.LARGE_INTEGER = 1;
......@@ -2210,7 +2212,7 @@ pub const Dir = struct {
22102212 var need_to_retry: bool = false;
22112213 parent_dir.deleteDir(name) catch |err| switch (err) {
22122214 error.FileNotFound => {},
2213 error.DirNotEmpty => need_to_retry = false,
2215 error.DirNotEmpty => need_to_retry = true,
22142216 else => |e| return e,
22152217 };
22162218
......@@ -2913,6 +2915,7 @@ pub const OpenSelfExeError = error{
29132915 /// On Windows, file paths cannot contain these characters:
29142916 /// '/', '*', '?', '"', '<', '>', '|'
29152917 BadPathName,
2918 Overflow,
29162919 Unexpected,
29172920} || os.OpenError || SelfExePathError || os.FlockError;
29182921
......@@ -2991,7 +2994,15 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
29912994 // TODO could this slice from 0 to out_len instead?
29922995 return mem.sliceTo(out_buffer, 0);
29932996 },
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 => {
29953006 // OpenBSD doesn't support getting the path of a running process, so try to guess it
29963007 if (os.argv.len == 0)
29973008 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
12141214 try testing.expectEqualStrings(expected_output, result);
12151215}
12161216
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 "".
12211220/// Examples:
12221221/// - `"main.zig"` ⇒ `".zig"`
12231222/// - `"src/main.zig"` ⇒ `".zig"`
lib/std/http.zig+1
......@@ -275,4 +275,5 @@ test {
275275 _ = Client;
276276 _ = Method;
277277 _ = Status;
278 _ = @import("http/test.zig");
278279}
lib/std/http/Client.zig+8-9
......@@ -645,7 +645,6 @@ pub const Request = struct {
645645 if (req.response.parser.state.isContent()) break;
646646 }
647647
648 req.response.headers = http.Headers{ .allocator = req.client.allocator, .owned = false };
649648 try req.response.parse(req.response.parser.header_bytes.items);
650649
651650 if (req.response.status == .switching_protocols) {
......@@ -765,7 +764,7 @@ pub const Request = struct {
765764 }
766765
767766 if (has_trail) {
768 req.response.headers = http.Headers{ .allocator = req.client.allocator, .owned = false };
767 req.response.headers.clearRetainingCapacity();
769768
770769 // The response headers before the trailers are already guaranteed to be valid, so they will always be parsed again and cannot return an error.
771770 // This will *only* fail for a malformed trailer.
......@@ -797,18 +796,18 @@ pub const Request = struct {
797796
798797 /// Write `bytes` to the server. The `transfer_encoding` request header determines how data will be sent.
799798 pub fn write(req: *Request, bytes: []const u8) WriteError!usize {
800 switch (req.headers.transfer_encoding) {
799 switch (req.transfer_encoding) {
801800 .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");
805804
806805 return bytes.len;
807806 },
808807 .content_length => |*len| {
809808 if (len.* < bytes.len) return error.MessageTooLong;
810809
811 const amt = try req.connection.data.conn.write(bytes);
810 const amt = try req.connection.data.buffered.write(bytes);
812811 len.* -= amt;
813812 return amt;
814813 },
......@@ -828,7 +827,7 @@ pub const Request = struct {
828827 /// Finish the body of a request. This notifies the server that you have no more data to send.
829828 pub fn finish(req: *Request) FinishError!void {
830829 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"),
832831 .content_length => |len| if (len != 0) return error.MessageNotCompleted,
833832 .none => {},
834833 }
......@@ -1019,7 +1018,7 @@ pub fn request(client: *Client, method: http.Method, uri: Uri, headers: http.Hea
10191018 .status = undefined,
10201019 .reason = undefined,
10211020 .version = undefined,
1022 .headers = undefined,
1021 .headers = http.Headers{ .allocator = client.allocator, .owned = false },
10231022 .parser = switch (options.header_strategy) {
10241023 .dynamic => |max| proto.HeadersParser.initDynamic(max),
10251024 .static => |buf| proto.HeadersParser.initStatic(buf),
lib/std/http/Headers.zig+73-11
......@@ -68,17 +68,7 @@ pub const Headers = struct {
6868 }
6969
7070 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();
8272 headers.index.deinit(headers.allocator);
8373 headers.list.deinit(headers.allocator);
8474
......@@ -255,6 +245,39 @@ pub const Headers = struct {
255245
256246 try out_stream.writeAll("\r\n");
257247 }
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 }
258281};
259282
260283test "Headers.append" {
......@@ -384,3 +407,42 @@ test "Headers consistency" {
384407 try h.formatCommaSeparated("foo", writer);
385408 try testing.expectEqualStrings("foo: bar, baz\r\n", fbs.getWritten());
386409}
410
411test "Headers.clearRetainingCapacity and clearAndFree" {
412 var h = Headers.init(std.testing.allocator);
413 defer h.deinit();
414
415 h.clearRetainingCapacity();
416
417 try h.append("foo", "bar");
418 try h.append("bar", "world");
419 try h.append("foo", "baz");
420 try h.append("baz", "hello");
421 try testing.expectEqual(@as(usize, 4), h.list.items.len);
422 try testing.expectEqual(@as(usize, 3), h.index.count());
423 const list_capacity = h.list.capacity;
424 const index_capacity = h.index.capacity();
425
426 h.clearRetainingCapacity();
427 try testing.expectEqual(@as(usize, 0), h.list.items.len);
428 try testing.expectEqual(@as(usize, 0), h.index.count());
429 try testing.expectEqual(list_capacity, h.list.capacity);
430 try testing.expectEqual(index_capacity, h.index.capacity());
431
432 try h.append("foo", "bar");
433 try h.append("bar", "world");
434 try h.append("foo", "baz");
435 try h.append("baz", "hello");
436 try testing.expectEqual(@as(usize, 4), h.list.items.len);
437 try testing.expectEqual(@as(usize, 3), h.index.count());
438 // Capacity should still be the same since we shouldn't have needed to grow
439 // when adding back the same fields
440 try testing.expectEqual(list_capacity, h.list.capacity);
441 try testing.expectEqual(index_capacity, h.index.capacity());
442
443 h.clearAndFree();
444 try testing.expectEqual(@as(usize, 0), h.list.items.len);
445 try testing.expectEqual(@as(usize, 0), h.index.count());
446 try testing.expectEqual(@as(usize, 0), h.list.capacity);
447 try testing.expectEqual(@as(usize, 0), h.index.capacity());
448}
lib/std/http/Server.zig+78-2
......@@ -336,8 +336,15 @@ pub const Response = struct {
336336 headers: http.Headers,
337337 request: Request,
338338
339 pub fn deinit(res: *Response) void {
340 res.server.allocator.destroy(res);
341 }
342
339343 /// Reset this response to its initial state. This must be called before handling a second request on the same connection.
340344 pub fn reset(res: *Response) void {
345 res.request.headers.deinit();
346 res.headers.deinit();
347
341348 switch (res.request.compression) {
342349 .none => {},
343350 .deflate => |*deflate| deflate.deinit(),
......@@ -356,8 +363,6 @@ pub const Response = struct {
356363 if (res.request.parser.header_bytes_owned) {
357364 res.request.parser.header_bytes.deinit(res.server.allocator);
358365 }
359
360 res.* = undefined;
361366 } else {
362367 res.request.parser.reset();
363368 }
......@@ -656,3 +661,74 @@ pub fn accept(server: *Server, options: HeaderStrategy) AcceptError!*Response {
656661
657662 return res;
658663}
664
665test "HTTP server handles a chunked transfer coding request" {
666 const builtin = @import("builtin");
667
668 // This test requires spawning threads.
669 if (builtin.single_threaded) {
670 return error.SkipZigTest;
671 }
672
673 const native_endian = comptime builtin.cpu.arch.endian();
674 if (builtin.zig_backend == .stage2_llvm and native_endian == .Big) {
675 // https://github.com/ziglang/zig/issues/13782
676 return error.SkipZigTest;
677 }
678
679 if (builtin.os.tag == .wasi) return error.SkipZigTest;
680
681 const allocator = std.testing.allocator;
682 const expect = std.testing.expect;
683
684 const max_header_size = 8192;
685 var server = std.http.Server.init(allocator, .{ .reuse_address = true });
686 defer server.deinit();
687
688 const address = try std.net.Address.parseIp("127.0.0.1", 0);
689 try server.listen(address);
690 const server_port = server.socket.listen_address.in.getPort();
691
692 const server_thread = try std.Thread.spawn(.{}, (struct {
693 fn apply(s: *std.http.Server) !void {
694 const res = try s.accept(.{ .dynamic = max_header_size });
695 defer res.deinit();
696 defer res.reset();
697 try res.wait();
698
699 try expect(res.request.transfer_encoding.? == .chunked);
700
701 const server_body: []const u8 = "message from server!\n";
702 res.transfer_encoding = .{ .content_length = server_body.len };
703 try res.headers.append("content-type", "text/plain");
704 try res.headers.append("connection", "close");
705 try res.do();
706
707 var buf: [128]u8 = undefined;
708 const n = try res.readAll(&buf);
709 try expect(std.mem.eql(u8, buf[0..n], "ABCD"));
710 _ = try res.writer().writeAll(server_body);
711 try res.finish();
712 }
713 }).apply, .{&server});
714
715 const request_bytes =
716 "POST / HTTP/1.1\r\n" ++
717 "Content-Type: text/plain\r\n" ++
718 "Transfer-Encoding: chunked\r\n" ++
719 "\r\n" ++
720 "1\r\n" ++
721 "A\r\n" ++
722 "1\r\n" ++
723 "B\r\n" ++
724 "2\r\n" ++
725 "CD\r\n" ++
726 "0\r\n" ++
727 "\r\n";
728
729 const stream = try std.net.tcpConnectToHost(allocator, "127.0.0.1", server_port);
730 defer stream.close();
731 _ = try stream.writeAll(request_bytes[0..]);
732
733 server_thread.join();
734}
lib/std/http/protocol.zig+6-2
......@@ -556,8 +556,12 @@ pub const HeadersParser = struct {
556556 switch (r.state) {
557557 .invalid => return error.HttpChunkInvalid,
558558 .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 }
561565 r.done = true;
562566
563567 return out_index;
lib/std/http/test.zig created+72
......@@ -0,0 +1,72 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4test "client requests server" {
5 const builtin = @import("builtin");
6
7 // This test requires spawning threads.
8 if (builtin.single_threaded) {
9 return error.SkipZigTest;
10 }
11
12 const native_endian = comptime builtin.cpu.arch.endian();
13 if (builtin.zig_backend == .stage2_llvm and native_endian == .Big) {
14 // https://github.com/ziglang/zig/issues/13782
15 return error.SkipZigTest;
16 }
17
18 if (builtin.os.tag == .wasi) return error.SkipZigTest;
19
20 const allocator = std.testing.allocator;
21
22 const max_header_size = 8192;
23 var server = std.http.Server.init(allocator, .{ .reuse_address = true });
24 defer server.deinit();
25
26 const address = try std.net.Address.parseIp("127.0.0.1", 0);
27 try server.listen(address);
28 const server_port = server.socket.listen_address.in.getPort();
29
30 const server_thread = try std.Thread.spawn(.{}, (struct {
31 fn apply(s: *std.http.Server) !void {
32 const res = try s.accept(.{ .dynamic = max_header_size });
33 defer res.deinit();
34 defer res.reset();
35 try res.wait();
36
37 const server_body: []const u8 = "message from server!\n";
38 res.transfer_encoding = .{ .content_length = server_body.len };
39 try res.headers.append("content-type", "text/plain");
40 try res.headers.append("connection", "close");
41 try res.do();
42
43 var buf: [128]u8 = undefined;
44 const n = try res.readAll(&buf);
45 try expect(std.mem.eql(u8, buf[0..n], "Hello, World!\n"));
46 _ = try res.writer().writeAll(server_body);
47 try res.finish();
48 }
49 }).apply, .{&server});
50
51 var uri_buf: [22]u8 = undefined;
52 const uri = try std.Uri.parse(try std.fmt.bufPrint(&uri_buf, "http://127.0.0.1:{d}", .{server_port}));
53 var client = std.http.Client{ .allocator = allocator };
54 defer client.deinit();
55 var client_headers = std.http.Headers{ .allocator = allocator };
56 defer client_headers.deinit();
57 var client_req = try client.request(.POST, uri, client_headers, .{});
58 defer client_req.deinit();
59
60 client_req.transfer_encoding = .{ .content_length = 14 }; // this will be checked to ensure you sent exactly 14 bytes
61 try client_req.start(); // this sends the request
62 try client_req.writeAll("Hello, ");
63 try client_req.writeAll("World!\n");
64 try client_req.finish();
65 try client_req.do(); // this waits for a response
66
67 const body = try client_req.reader().readAllAlloc(allocator, 8192 * 1024);
68 defer allocator.free(body);
69 try expect(std.mem.eql(u8, body, "message from server!\n"));
70
71 server_thread.join();
72}
lib/std/macho.zig+2-2
......@@ -540,13 +540,13 @@ pub const dylib_command = extern struct {
540540 dylib: dylib,
541541};
542542
543/// Dynamicaly linked shared libraries are identified by two things. The
543/// Dynamically linked shared libraries are identified by two things. The
544544/// pathname (the name of the library as found for execution), and the
545545/// compatibility version number. The pathname must match and the compatibility
546546/// number in the user of the library must be greater than or equal to the
547547/// library being used. The time stamp is used to record the time a library was
548548/// 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.
550550pub const dylib = extern struct {
551551 /// library's pathname (offset pointing at the end of dylib_command)
552552 name: u32,
lib/std/math.zig+4-3
......@@ -782,7 +782,8 @@ fn testOverflow() !void {
782782}
783783
784784/// 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.
786787pub fn absInt(x: anytype) !@TypeOf(x) {
787788 const T = @TypeOf(x);
788789 return switch (@typeInfo(T)) {
......@@ -1015,8 +1016,8 @@ pub inline fn fabs(value: anytype) @TypeOf(value) {
10151016}
10161017
10171018/// 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.
10201021pub fn absCast(x: anytype) switch (@typeInfo(@TypeOf(x))) {
10211022 .ComptimeInt => comptime_int,
10221023 .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 {
227227/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this
228228/// function used, examine closely - it may be a code smell.
229229/// 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.
231231pub fn zeroes(comptime T: type) T {
232232 switch (@typeInfo(T)) {
233233 .ComptimeInt, .Int, .ComptimeFloat, .Float => {
lib/std/net.zig+13
......@@ -1867,6 +1867,7 @@ pub const StreamServer = struct {
18671867 /// Copied from `Options` on `init`.
18681868 kernel_backlog: u31,
18691869 reuse_address: bool,
1870 reuse_port: bool,
18701871
18711872 /// `undefined` until `listen` returns successfully.
18721873 listen_address: Address,
......@@ -1881,6 +1882,9 @@ pub const StreamServer = struct {
18811882
18821883 /// Enable SO.REUSEADDR on the socket.
18831884 reuse_address: bool = false,
1885
1886 /// Enable SO.REUSEPORT on the socket.
1887 reuse_port: bool = false,
18841888 };
18851889
18861890 /// After this call succeeds, resources have been acquired and must
......@@ -1890,6 +1894,7 @@ pub const StreamServer = struct {
18901894 .sockfd = null,
18911895 .kernel_backlog = options.kernel_backlog,
18921896 .reuse_address = options.reuse_address,
1897 .reuse_port = options.reuse_port,
18931898 .listen_address = undefined,
18941899 };
18951900 }
......@@ -1920,6 +1925,14 @@ pub const StreamServer = struct {
19201925 &mem.toBytes(@as(c_int, 1)),
19211926 );
19221927 }
1928 if (@hasDecl(os.SO, "REUSEPORT") and self.reuse_port) {
1929 try os.setsockopt(
1930 sockfd,
1931 os.SOL.SOCKET,
1932 os.SO.REUSEPORT,
1933 &mem.toBytes(@as(c_int, 1)),
1934 );
1935 }
19231936
19241937 var socklen = address.getOsSockLen();
19251938 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" {
230230 try await client_frame;
231231}
232232
233test "listen on an in use port" {
234 if (builtin.os.tag != .linux and comptime !builtin.os.tag.isDarwin()) {
235 // TODO build abstractions for other operating systems
236 return error.SkipZigTest;
237 }
238
239 const localhost = try net.Address.parseIp("127.0.0.1", 0);
240
241 var server1 = net.StreamServer.init(net.StreamServer.Options{
242 .reuse_port = true,
243 });
244 defer server1.deinit();
245 try server1.listen(localhost);
246
247 var server2 = net.StreamServer.init(net.StreamServer.Options{
248 .reuse_port = true,
249 });
250 defer server2.deinit();
251 try server2.listen(server1.listen_address);
252}
253
233254fn testClientToHost(allocator: mem.Allocator, name: []const u8, port: u16) anyerror!void {
234255 if (builtin.os.tag == .wasi) return error.SkipZigTest;
235256
lib/std/os.zig+4-10
......@@ -4722,11 +4722,8 @@ pub fn sysctl(
47224722 newp: ?*anyopaque,
47234723 newlen: usize,
47244724) 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");
47304727 }
47314728
47324729 const name_len = math.cast(c_uint, name.len) orelse return error.NameTooLong;
......@@ -4747,11 +4744,8 @@ pub fn sysctlbynameZ(
47474744 newp: ?*anyopaque,
47484745 newlen: usize,
47494746) 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");
47554749 }
47564750
47574751 switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {
lib/std/os/linux.zig+4-1
......@@ -3464,7 +3464,10 @@ pub const CAP = struct {
34643464 pub const WAKE_ALARM = 35;
34653465 pub const BLOCK_SUSPEND = 36;
34663466 pub const AUDIT_READ = 37;
3467 pub const LAST_CAP = AUDIT_READ;
3467 pub const PERFMON = 38;
3468 pub const BPF = 39;
3469 pub const CHECKPOINT_RESTORE = 40;
3470 pub const LAST_CAP = CHECKPOINT_RESTORE;
34683471
34693472 pub fn valid(x: u8) bool {
34703473 return x >= 0 and x <= LAST_CAP;
lib/std/os/linux/seccomp.zig+1-1
......@@ -20,7 +20,7 @@
2020//!
2121//! 1. Each CPU architecture supported by Linux has its own unique ABI and
2222//! 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,
2424//! filters cannot be assumed to be portable without consulting documentation
2525//! like syscalls(2) and testing on target hardware. This also requires
2626//! 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" {
11011101 defer tmp.cleanup();
11021102
11031103 var file = try tmp.dir.createFile("foo", .{});
1104 defer file.close();
1105
11041106 try expectEqual(os.isatty(file.handle), false);
11051107}
11061108
lib/std/process.zig+10-4
......@@ -818,7 +818,8 @@ pub const ArgIterator = struct {
818818 }
819819};
820820
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.
822823pub fn args() ArgIterator {
823824 return ArgIterator.init();
824825}
......@@ -1162,12 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {
11621163 .linux => {
11631164 return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
11641165 },
1165 .freebsd => {
1166 .freebsd, .netbsd, .openbsd, .dragonfly, .macos => {
11661167 var physmem: c_ulong = undefined;
11671168 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) {
11691175 error.NameTooLong, error.UnknownName => unreachable,
1170 else => |e| return e,
1176 else => return error.UnknownTotalSystemMemory,
11711177 };
11721178 return @intCast(usize, physmem);
11731179 },
lib/std/rand.zig+2
......@@ -389,6 +389,8 @@ pub const Random = struct {
389389
390390 /// Randomly selects an index into `proportions`, where the likelihood of each
391391 /// 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.
392394 ///
393395 /// This is useful for selecting an item from a slice where weights are not equal.
394396 /// `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 {
3535 pub fn fileSize(header: Header) !u64 {
3636 const raw = header.bytes[124..][0..12];
3737 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");
3939 if (rtrimmed.len == 0) return 0;
4040 return std.fmt.parseInt(u64, rtrimmed, 8);
4141 }
......@@ -122,13 +122,16 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
122122 .directory => {
123123 const file_name = try stripComponents(unstripped_file_name, options.strip_components);
124124 if (file_name.len != 0) {
125 try dir.makeDir(file_name);
125 try dir.makePath(file_name);
126126 }
127127 },
128128 .normal => {
129129 if (file_size == 0 and unstripped_file_name.len == 0) return;
130130 const file_name = try stripComponents(unstripped_file_name, options.strip_components);
131131
132 if (std.fs.path.dirname(file_name)) |dir_name| {
133 try dir.makePath(dir_name);
134 }
132135 var file = try dir.createFile(file_name, .{});
133136 defer file.close();
134137
src/Air.zig+1-1
......@@ -681,7 +681,7 @@ pub const Inst = struct {
681681 /// Uses the `un_op` field.
682682 tag_name,
683683
684 /// Given an error value, return the error name. Result type is always `[:0] const u8`.
684 /// Given an error value, return the error name. Result type is always `[:0]const u8`.
685685 /// Uses the `un_op` field.
686686 error_name,
687687
src/AstGen.zig+75-100
......@@ -839,12 +839,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
839839 .slice_open => {
840840 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
841841
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);
846843 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);
848845 const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{
849846 .lhs = lhs,
850847 .start = start,
......@@ -854,14 +851,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
854851 .slice => {
855852 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
856853
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);
861855 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice);
862856 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start);
863857 const end = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end);
864 try emitDbgStmt(gz, line, column);
858 try emitDbgStmt(gz, cursor);
865859 const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{
866860 .lhs = lhs,
867861 .start = start,
......@@ -872,15 +866,12 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
872866 .slice_sentinel => {
873867 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
874868
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);
879870 const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel);
880871 const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start);
881872 const end = if (extra.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end) else .none;
882873 const sentinel = try expr(gz, scope, .{ .rl = .none }, extra.sentinel);
883 try emitDbgStmt(gz, line, column);
874 try emitDbgStmt(gz, cursor);
884875 const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{
885876 .lhs = lhs,
886877 .start = start,
......@@ -914,20 +905,16 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
914905 .ref => {
915906 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
916907
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);
921910
922911 return gz.addUnNode(.optional_payload_safe_ptr, lhs, node);
923912 },
924913 else => {
925914 const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);
926915
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);
931918
932919 return rvalue(gz, ri, try gz.addUnNode(.optional_payload_safe, lhs, node), node);
933920 },
......@@ -3330,23 +3317,17 @@ fn assignOp(
33303317
33313318 const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs);
33323319
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 };
33433324 const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node);
33443325 const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node);
33453326 const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = lhs_type } }, node_datas[infix_node].rhs);
33463327
33473328 switch (op_inst_tag) {
33483329 .add, .sub, .mul, .div, .mod_rem => {
3349 try emitDbgStmt(gz, line, column);
3330 try emitDbgStmt(gz, cursor);
33503331 },
33513332 else => {},
33523333 }
......@@ -5360,8 +5341,7 @@ fn tryExpr(
53605341 if (!parent_gz.is_comptime) {
53615342 try emitDbgNode(parent_gz, node);
53625343 }
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 };
53655345
53665346 const operand_ri: ResultInfo = switch (ri.rl) {
53675347 .ref => .{ .rl = .ref, .ctx = .error_handling_expr },
......@@ -5382,7 +5362,7 @@ fn tryExpr(
53825362 };
53835363 const err_code = try else_scope.addUnNode(err_tag, operand, node);
53845364 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);
53865366 _ = try else_scope.addUnNode(.ret_node, err_code, node);
53875367
53885368 try else_scope.setTryBody(try_inst, operand);
......@@ -5607,10 +5587,8 @@ fn addFieldAccess(
56075587 const str_index = try astgen.identAsString(field_ident);
56085588 const lhs = try expr(gz, scope, lhs_ri, object_node);
56095589
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);
56145592
56155593 return gz.addPlNode(tag, node, Zir.Inst.Field{
56165594 .lhs = lhs,
......@@ -5630,24 +5608,20 @@ fn arrayAccess(
56305608 .ref => {
56315609 const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs);
56325610
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);
56365612
56375613 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);
5638 try emitDbgStmt(gz, line, column);
5614 try emitDbgStmt(gz, cursor);
56395615
56405616 return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs });
56415617 },
56425618 else => {
56435619 const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs);
56445620
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);
56485622
56495623 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs);
5650 try emitDbgStmt(gz, line, column);
5624 try emitDbgStmt(gz, cursor);
56515625
56525626 return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node);
56535627 },
......@@ -5674,21 +5648,15 @@ fn simpleBinOp(
56745648 }
56755649
56765650 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 };
56875655 const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node);
56885656
56895657 switch (op_inst_tag) {
56905658 .add, .sub, .mul, .div, .mod_rem => {
5691 try emitDbgStmt(gz, line, column);
5659 try emitDbgStmt(gz, cursor);
56925660 },
56935661 else => {},
56945662 }
......@@ -6787,14 +6755,15 @@ fn switchExpr(
67876755 }
67886756
67896757 const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none };
6758
67906759 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
67936762 const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node);
67946763 const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond;
67956764 const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node);
67966765 // 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);
67986767 // We need the type of the operand to use as the result location for all the prong items.
67996768 const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node);
68006769 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
71547123 if (!gz.is_comptime) {
71557124 try emitDbgNode(gz, node);
71567125 }
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 };
71597127
71607128 const defer_outer = &astgen.fn_block.?.base;
71617129
......@@ -7179,13 +7147,13 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
71797147 const defer_counts = countDefers(defer_outer, scope);
71807148 if (!defer_counts.need_err_code) {
71817149 try genDefers(gz, defer_outer, scope, .both_sans_err);
7182 try emitDbgStmt(gz, ret_line, ret_column);
7150 try emitDbgStmt(gz, ret_lc);
71837151 _ = try gz.addStrTok(.ret_err_value, err_name_str_index, ident_token);
71847152 return Zir.Inst.Ref.unreachable_value;
71857153 }
71867154 const err_code = try gz.addStrTok(.ret_err_value_code, err_name_str_index, ident_token);
71877155 try genDefers(gz, defer_outer, scope, .{ .both = err_code });
7188 try emitDbgStmt(gz, ret_line, ret_column);
7156 try emitDbgStmt(gz, ret_lc);
71897157 _ = try gz.addUnNode(.ret_node, err_code, node);
71907158 return Zir.Inst.Ref.unreachable_value;
71917159 }
......@@ -7210,7 +7178,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
72107178 // As our last action before the return, "pop" the error trace if needed
72117179 _ = try gz.addRestoreErrRetIndex(.ret, .always);
72127180
7213 try emitDbgStmt(gz, ret_line, ret_column);
7181 try emitDbgStmt(gz, ret_lc);
72147182 try gz.addRet(ri, operand, node);
72157183 return Zir.Inst.Ref.unreachable_value;
72167184 },
......@@ -7218,7 +7186,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
72187186 // Value is always an error. Emit both error defers and regular defers.
72197187 const err_code = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand;
72207188 try genDefers(gz, defer_outer, scope, .{ .both = err_code });
7221 try emitDbgStmt(gz, ret_line, ret_column);
7189 try emitDbgStmt(gz, ret_lc);
72227190 try gz.addRet(ri, operand, node);
72237191 return Zir.Inst.Ref.unreachable_value;
72247192 },
......@@ -7227,7 +7195,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
72277195 if (!defer_counts.have_err) {
72287196 // Only regular defers; no branch needed.
72297197 try genDefers(gz, defer_outer, scope, .normal_only);
7230 try emitDbgStmt(gz, ret_line, ret_column);
7198 try emitDbgStmt(gz, ret_lc);
72317199
72327200 // As our last action before the return, "pop" the error trace if needed
72337201 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
72507218 // As our last action before the return, "pop" the error trace if needed
72517219 _ = try then_scope.addRestoreErrRetIndex(.ret, .always);
72527220
7253 try emitDbgStmt(&then_scope, ret_line, ret_column);
7221 try emitDbgStmt(&then_scope, ret_lc);
72547222 try then_scope.addRet(ri, operand, node);
72557223
72567224 var else_scope = gz.makeSubBlock(scope);
......@@ -7260,7 +7228,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
72607228 .both = try else_scope.addUnNode(.err_union_code, result, node),
72617229 };
72627230 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);
72647232 try else_scope.addRet(ri, operand, node);
72657233
72667234 try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0);
......@@ -8174,6 +8142,7 @@ fn builtinCall(
81748142 .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node),
81758143 .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node),
81768144 .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node),
8145 .in_comptime => return rvalue(gz, ri, try gz.addNodeExtended(.in_comptime, node), node),
81778146
81788147 .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info),
81798148 .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of),
......@@ -8649,11 +8618,14 @@ fn typeCast(
86498618 rhs_node: Ast.Node.Index,
86508619 tag: Zir.Inst.Tag,
86518620) InnerError!Zir.Inst.Ref {
8652 try emitDbgNode(gz, node);
8621 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
8622 const result_type = try typeExpr(gz, scope, lhs_node);
8623 const operand = try expr(gz, scope, .{ .rl = .none }, rhs_node);
86538624
8625 try emitDbgStmt(gz, cursor);
86548626 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,
86578629 });
86588630 return rvalue(gz, ri, result, node);
86598631}
......@@ -8680,14 +8652,15 @@ fn simpleUnOp(
86808652 operand_node: Ast.Node.Index,
86818653 tag: Zir.Inst.Tag,
86828654) 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);
86878656 const operand = if (tag == .compile_error)
86888657 try comptimeExpr(gz, scope, operand_ri, operand_node)
86898658 else
86908659 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 }
86918664 const result = try gz.addUnNode(tag, operand, node);
86928665 return rvalue(gz, ri, result, node);
86938666}
......@@ -8759,12 +8732,12 @@ fn divBuiltin(
87598732 rhs_node: Ast.Node.Index,
87608733 tag: Zir.Inst.Tag,
87618734) InnerError!Zir.Inst.Ref {
8762 try emitDbgNode(gz, node);
8735 const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
8736 const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node);
8737 const rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node);
87638738
8764 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
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 });
87688741 return rvalue(gz, ri, result, node);
87698742}
87708743
......@@ -8813,23 +8786,21 @@ fn shiftOp(
88138786 rhs_node: Ast.Node.Index,
88148787 tag: Zir.Inst.Tag,
88158788) InnerError!Zir.Inst.Ref {
8816 var line = gz.astgen.source_line - gz.decl_line;
8817 var column = gz.astgen.source_column;
88188789 const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node);
88198790
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 };
88288795
88298796 const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node);
88308797 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node);
88318798
8832 try emitDbgStmt(gz, line, column);
8799 switch (gz.astgen.tree.nodes.items(.tag)[node]) {
8800 .shl, .shr => try emitDbgStmt(gz, cursor),
8801 else => undefined,
8802 }
8803
88338804 const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{
88348805 .lhs = lhs,
88358806 .rhs = rhs,
......@@ -12593,16 +12564,20 @@ fn detectLocalShadowing(
1259312564 };
1259412565}
1259512566
12567const LineColumn = struct { u32, u32 };
12568
1259612569/// Advances the source cursor to the main token of `node` if not in comptime scope.
1259712570/// Usually paired with `emitDbgStmt`.
12598fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) void {
12599 if (gz.is_comptime) return;
12571fn 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 };
1260012573
1260112574 const tree = gz.astgen.tree;
1260212575 const token_starts = tree.tokens.items(.start);
1260312576 const main_tokens = tree.nodes.items(.main_token);
1260412577 const node_start = token_starts[main_tokens[node]];
1260512578 gz.astgen.advanceSourceCursor(node_start);
12579
12580 return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column };
1260612581}
1260712582
1260812583/// Advances the source cursor to the beginning of `node`.
......@@ -12806,13 +12781,13 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {
1280612781 return @intCast(u32, count);
1280712782}
1280812783
12809fn emitDbgStmt(gz: *GenZir, line: u32, column: u32) !void {
12784fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {
1281012785 if (gz.is_comptime) return;
1281112786
1281212787 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
1281312788 .dbg_stmt = .{
12814 .line = line,
12815 .column = column,
12789 .line = lc[0],
12790 .column = lc[1],
1281612791 },
1281712792 } });
1281812793}
src/Autodoc.zig+2-2
......@@ -4076,7 +4076,7 @@ fn analyzeFancyFunction(
40764076 else => null,
40774077 };
40784078
4079 // if we're analyzing a funcion signature (ie without body), we
4079 // if we're analyzing a function signature (ie without body), we
40804080 // actually don't have an ast_node reserved for us, but since
40814081 // we don't have a name, we don't need it.
40824082 const src = if (fn_info.body.len == 0) 0 else self_ast_node_index;
......@@ -4229,7 +4229,7 @@ fn analyzeFunction(
42294229 } else break :blk ret_type_ref;
42304230 };
42314231
4232 // if we're analyzing a funcion signature (ie without body), we
4232 // if we're analyzing a function signature (ie without body), we
42334233 // actually don't have an ast_node reserved for us, but since
42344234 // we don't have a name, we don't need it.
42354235 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 {
5858 has_decl,
5959 has_field,
6060 import,
61 in_comptime,
6162 int_cast,
6263 int_to_enum,
6364 int_to_error,
......@@ -560,6 +561,13 @@ pub const list = list: {
560561 .param_count = 1,
561562 },
562563 },
564 .{
565 "@inComptime",
566 .{
567 .tag = .in_comptime,
568 .param_count = 0,
569 },
570 },
563571 .{
564572 "@intCast",
565573 .{
src/Module.zig+1-1
......@@ -6626,7 +6626,7 @@ pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {
66266626 .safety_check_formatted => mod.comp.bin_file.options.use_llvm,
66276627 .error_return_trace => mod.comp.bin_file.options.use_llvm,
66286628 .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(),
66306630 .field_reordering => mod.comp.bin_file.options.use_llvm,
66316631 };
66326632}
src/Sema.zig+44-20
......@@ -1166,6 +1166,7 @@ fn analyzeBodyInner(
11661166 .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode),
11671167 .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode),
11681168 .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode),
1169 .in_comptime => try sema.zirInComptime( block),
11691170 // zig fmt: on
11701171
11711172 .fence => {
......@@ -4155,7 +4156,7 @@ fn validateUnionInit(
41554156 const msg = try sema.errMsg(
41564157 block,
41574158 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",
41594160 .{},
41604161 );
41614162 errdefer msg.destroy(sema.gpa);
......@@ -9646,7 +9647,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
96469647 .Union => "union",
96479648 else => unreachable,
96489649 };
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", .{
96509651 dest_ty.fmt(sema.mod), container,
96519652 });
96529653 },
......@@ -9709,7 +9710,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97099710 .Union => "union",
97109711 else => unreachable,
97119712 };
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", .{
97139714 operand_ty.fmt(sema.mod), container,
97149715 });
97159716 },
......@@ -19626,7 +19627,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1962619627 }
1962719628
1962819629 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)) {
1963019631 if (!ptr_ty.isAllowzeroPtr()) {
1963119632 const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
1963219633 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
1985219853
1985319854 try sema.requireRuntimeBlock(block, src, null);
1985419855 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))
1985619857 {
1985719858 const ptr_int = try block.addUnOp(.ptrtoint, ptr);
1985819859 const is_non_zero = try block.addBinOp(.cmp_neq, ptr_int, .zero_usize);
......@@ -22466,6 +22467,18 @@ fn zirWorkItem(
2246622467 });
2246722468}
2246822469
22470fn zirInComptime(
22471 sema: *Sema,
22472 block: *Block,
22473) CompileError!Air.Inst.Ref {
22474 _ = sema;
22475 if (block.is_comptime) {
22476 return Air.Inst.Ref.bool_true;
22477 } else {
22478 return Air.Inst.Ref.bool_false;
22479 }
22480}
22481
2246922482fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {
2247022483 if (block.is_comptime) {
2247122484 const msg = msg: {
......@@ -23738,7 +23751,6 @@ fn fieldCallBind(
2373823751 {
2373923752 const first_param_type = decl_type.fnParamType(0);
2374023753 const first_param_tag = first_param_type.tag();
23741 var opt_buf: Type.Payload.ElemType = undefined;
2374223754 // zig fmt: off
2374323755 if (first_param_tag == .var_args_param or
2374423756 first_param_tag == .generic_poison or (
......@@ -23764,17 +23776,29 @@ fn fieldCallBind(
2376423776 .arg0_inst = deref,
2376523777 });
2376623778 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
2377823802 first_param_type.errorUnionPayload().eql(concrete_ty, sema.mod))
2377923803 {
2378023804 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
......@@ -26434,7 +26458,7 @@ fn coerceVarArgParam(
2643426458 .ComptimeInt, .ComptimeFloat => return sema.fail(
2643526459 block,
2643626460 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",
2643826462 .{},
2643926463 ),
2644026464 .Fn => blk: {
......@@ -27718,7 +27742,7 @@ fn coerceCompatiblePtrs(
2771827742 try sema.requireRuntimeBlock(block, inst_src, null);
2771927743 const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero();
2772027744 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))
2772227746 {
2772327747 const actual_ptr = if (inst_ty.isSlice())
2772427748 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
......@@ -27891,7 +27915,7 @@ fn coerceAnonStructToUnion(
2789127915 const msg = if (field_count > 1) try sema.errMsg(
2789227916 block,
2789327917 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",
2789527919 .{},
2789627920 ) else try sema.errMsg(
2789727921 block,
src/Zir.zig+5-2
......@@ -1994,10 +1994,10 @@ pub const Inst = struct {
19941994 /// Implement builtin `@cVaArg`.
19951995 /// `operand` is payload index to `BinNode`.
19961996 c_va_arg,
1997 /// Implement builtin `@cVaStart`.
1997 /// Implement builtin `@cVaCopy`.
19981998 /// `operand` is payload index to `UnNode`.
19991999 c_va_copy,
2000 /// Implement builtin `@cVaStart`.
2000 /// Implement builtin `@cVaEnd`.
20012001 /// `operand` is payload index to `UnNode`.
20022002 c_va_end,
20032003 /// Implement builtin `@cVaStart`.
......@@ -2018,6 +2018,9 @@ pub const Inst = struct {
20182018 /// Implements the `@workGroupId` builtin.
20192019 /// `operand` is payload index to `UnNode`.
20202020 work_group_id,
2021 /// Implements the `@inComptime` builtin.
2022 /// `operand` is `src_node: i32`.
2023 in_comptime,
20212024
20222025 pub const InstData = struct {
20232026 opcode: Extended,
src/arch/wasm/CodeGen.zig+90-3
......@@ -1946,6 +1946,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19461946 .ret_addr => func.airRetAddr(inst),
19471947 .tag_name => func.airTagName(inst),
19481948
1949 .error_set_has_value => func.airErrorSetHasValue(inst),
1950
19491951 .mul_sat,
19501952 .mod,
19511953 .assembly,
......@@ -1967,7 +1969,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
19671969 .set_err_return_trace,
19681970 .save_err_return_trace_index,
19691971 .is_named_enum_value,
1970 .error_set_has_value,
19711972 .addrspace_cast,
19721973 .vector_store_elem,
19731974 .c_va_arg,
......@@ -3338,9 +3339,14 @@ fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
33383339fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
33393340 const un_op = func.air.instructions.items(.data)[inst].un_op;
33403341 const operand = try func.resolveInst(un_op);
3342 const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
3343 const errors_len = WValue{ .memory = sym_index };
33413344
3342 _ = operand;
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});
33443350}
33453351
33463352fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
......@@ -6510,3 +6516,84 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
65106516 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, func.target);
65116517 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
65126518}
6519
6520fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6521 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
6522
6523 const operand = try func.resolveInst(ty_op.operand);
6524 const error_set_ty = func.air.getRefType(ty_op.ty);
6525 const result = try func.allocLocal(Type.bool);
6526
6527 const names = error_set_ty.errorSetNames();
6528 var values = try std.ArrayList(u32).initCapacity(func.gpa, names.len);
6529 defer values.deinit();
6530
6531 const module = func.bin_file.base.options.module.?;
6532 var lowest: ?u32 = null;
6533 var highest: ?u32 = null;
6534 for (names) |name| {
6535 const err_int = module.global_error_set.get(name).?;
6536 if (lowest) |*l| {
6537 if (err_int < l.*) {
6538 l.* = err_int;
6539 }
6540 } else {
6541 lowest = err_int;
6542 }
6543 if (highest) |*h| {
6544 if (err_int > h.*) {
6545 highest = err_int;
6546 }
6547 } else {
6548 highest = err_int;
6549 }
6550
6551 values.appendAssumeCapacity(err_int);
6552 }
6553
6554 // start block for 'true' branch
6555 try func.startBlock(.block, wasm.block_empty);
6556 // start block for 'false' branch
6557 try func.startBlock(.block, wasm.block_empty);
6558 // block for the jump table itself
6559 try func.startBlock(.block, wasm.block_empty);
6560
6561 // lower operand to determine jump table target
6562 try func.emitWValue(operand);
6563 try func.addImm32(@intCast(i32, lowest.?));
6564 try func.addTag(.i32_sub);
6565
6566 // Account for default branch so always add '1'
6567 const depth = @intCast(u32, highest.? - lowest.? + 1);
6568 const jump_table: Mir.JumpTable = .{ .length = depth };
6569 const table_extra_index = try func.addExtra(jump_table);
6570 try func.addInst(.{ .tag = .br_table, .data = .{ .payload = table_extra_index } });
6571 try func.mir_extra.ensureUnusedCapacity(func.gpa, depth);
6572
6573 var value: u32 = lowest.?;
6574 while (value <= highest.?) : (value += 1) {
6575 const idx: u32 = blk: {
6576 for (values.items) |val| {
6577 if (val == value) break :blk 1;
6578 }
6579 break :blk 0;
6580 };
6581 func.mir_extra.appendAssumeCapacity(idx);
6582 }
6583 try func.endBlock();
6584
6585 // 'false' branch (i.e. error set does not have value
6586 // ensure we set local to 0 in case the local was re-used.
6587 try func.addImm32(0);
6588 try func.addLabel(.local_set, result.local.value);
6589 try func.addLabel(.br, 1);
6590 try func.endBlock();
6591
6592 // 'true' branch
6593 try func.addImm32(1);
6594 try func.addLabel(.local_set, result.local.value);
6595 try func.addLabel(.br, 0);
6596 try func.endBlock();
6597
6598 return func.finishAir(inst, result, &.{ty_op.operand});
6599}
src/clang.zig+9
......@@ -460,6 +460,9 @@ pub const Expr = opaque {
460460
461461 pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
462462 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;
463466};
464467
465468pub const FieldDecl = opaque {
......@@ -1053,6 +1056,12 @@ pub const InitListExpr = opaque {
10531056 pub const getArrayFiller = ZigClangInitListExpr_getArrayFiller;
10541057 extern fn ZigClangInitListExpr_getArrayFiller(*const InitListExpr) *const Expr;
10551058
1059 pub const hasArrayFiller = ZigClangInitListExpr_hasArrayFiller;
1060 extern fn ZigClangInitListExpr_hasArrayFiller(*const InitListExpr) bool;
1061
1062 pub const isStringLiteralInit = ZigClangInitListExpr_isStringLiteralInit;
1063 extern fn ZigClangInitListExpr_isStringLiteralInit(*const InitListExpr) bool;
1064
10561065 pub const getNumInits = ZigClangInitListExpr_getNumInits;
10571066 extern fn ZigClangInitListExpr_getNumInits(*const InitListExpr) c_uint;
10581067
src/link/NvPtx.zig+1-1
......@@ -1,4 +1,4 @@
1//! NVidia PTX (Paralle Thread Execution)
1//! NVidia PTX (Parallel Thread Execution)
22//! https://docs.nvidia.com/cuda/parallel-thread-execution/index.html
33//! For this we rely on the nvptx backend of LLVM
44//! 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 {
12091209 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
12101210 }
12111211 }
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 }
12121217}
12131218
12141219// Tries to find a global symbol by its name. Returns null when not found,
......@@ -2185,6 +2190,43 @@ fn setupInitFunctions(wasm: *Wasm) !void {
21852190 std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);
21862191}
21872192
2193/// Generates an atom containing the global error set' size.
2194/// This will only be generated if the symbol exists.
2195fn setupErrorsLen(wasm: *Wasm) !void {
2196 const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return;
2197
2198 const errors_len = wasm.base.options.module.?.global_error_set.count();
2199 // overwrite existing atom if it already exists (maybe the error set has increased)
2200 // if not, allcoate a new atom.
2201 const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {
2202 const atom = wasm.getAtomPtr(index);
2203 if (atom.next) |next_atom_index| {
2204 const next_atom = wasm.getAtomPtr(next_atom_index);
2205 next_atom.prev = atom.prev;
2206 atom.next = null;
2207 }
2208 if (atom.prev) |prev_index| {
2209 const prev_atom = wasm.getAtomPtr(prev_index);
2210 prev_atom.next = atom.next;
2211 atom.prev = null;
2212 }
2213 atom.deinit(wasm);
2214 break :blk index;
2215 } else new_atom: {
2216 const atom_index = @intCast(Atom.Index, wasm.managed_atoms.items.len);
2217 try wasm.symbol_atom.put(wasm.base.allocator, loc, atom_index);
2218 try wasm.managed_atoms.append(wasm.base.allocator, undefined);
2219 break :new_atom atom_index;
2220 };
2221 const atom = wasm.getAtomPtr(atom_index);
2222 atom.* = Atom.empty;
2223 atom.sym_index = loc.index;
2224 atom.size = 2;
2225 try atom.code.writer(wasm.base.allocator).writeIntLittle(u16, @intCast(u16, errors_len));
2226
2227 try wasm.parseAtom(atom_index, .{ .data = .read_only });
2228}
2229
21882230/// Creates a function body for the `__wasm_call_ctors` symbol.
21892231/// Loops over all constructors found in `init_funcs` and calls them
21902232/// 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
33173359 // So we can rebuild the binary file on each incremental update
33183360 defer wasm.resetState();
33193361 try wasm.setupInitFunctions();
3362 try wasm.setupErrorsLen();
33203363 try wasm.setupStart();
33213364 try wasm.setupImports();
33223365 if (wasm.base.options.module) |mod| {
src/main.zig+2-2
......@@ -402,8 +402,8 @@ const usage_build_generic =
402402 \\ --name [name] Override root name (not a file path)
403403 \\ -O [mode] Choose what to optimize for
404404 \\ 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
407407 \\ ReleaseSmall Optimize for small binary, safety off
408408 \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name
409409 \\ deps: [dep],[dep],...
src/print_zir.zig+1
......@@ -466,6 +466,7 @@ const Writer = struct {
466466 .frame_address,
467467 .breakpoint,
468468 .c_va_start,
469 .in_comptime,
469470 => try self.writeExtNode(stream, extended),
470471
471472 .builtin_src => {
src/translate_c.zig+27-8
......@@ -2697,6 +2697,13 @@ fn transInitListExprArray(
26972697 return Tag.empty_array.create(c.arena, child_type);
26982698 }
26992699
2700 if (expr.isStringLiteralInit()) {
2701 assert(init_count == 1);
2702 const init_expr = expr.getInit(0);
2703 const string_literal = init_expr.castToStringLiteral().?;
2704 return try transStringLiteral(c, scope, string_literal, .used);
2705 }
2706
27002707 const init_node = if (init_count != 0) blk: {
27012708 const init_list = try c.arena.alloc(Node, init_count);
27022709
......@@ -2714,6 +2721,7 @@ fn transInitListExprArray(
27142721 break :blk init_node;
27152722 } else null;
27162723
2724 assert(expr.hasArrayFiller());
27172725 const filler_val_expr = expr.getArrayFiller();
27182726 const filler_node = try Tag.array_filler.create(c.arena, .{
27192727 .type = child_type,
......@@ -4176,6 +4184,17 @@ fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
41764184 try c.global_scope.nodes.append(decl_node);
41774185}
41784186
4187fn transQualTypeInitializedStringLiteral(c: *Context, elem_ty: Node, string_lit: *const clang.StringLiteral) TypeError!Node {
4188 const string_lit_size = string_lit.getLength();
4189 const array_size = @intCast(usize, string_lit_size);
4190
4191 // incomplete array initialized with empty string, will be translated as [1]T{0}
4192 // see https://github.com/ziglang/zig/issues/8256
4193 if (array_size == 0) return Tag.array_type.create(c.arena, .{ .len = 1, .elem_type = elem_ty });
4194
4195 return Tag.null_sentinel_array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
4196}
4197
41794198/// Translate a qualtype for a variable with an initializer. This only matters
41804199/// for incomplete arrays, since the initializer determines the size of the array.
41814200fn transQualTypeInitialized(
......@@ -4193,18 +4212,18 @@ fn transQualTypeInitialized(
41934212 switch (decl_init.getStmtClass()) {
41944213 .StringLiteralClass => {
41954214 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);
42044216 },
42054217 .InitListExprClass => {
42064218 const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);
42074219 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
42084227 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
42094228 },
42104229 else => {},
src/zig_clang.cpp+16
......@@ -2382,6 +2382,12 @@ bool ZigClangExpr_EvaluateAsConstantExpr(const ZigClangExpr *self, ZigClangExprE
23822382 return true;
23832383}
23842384
2385const ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self) {
2386 auto casted_self = reinterpret_cast<const clang::Expr *>(self);
2387 auto cast = clang::dyn_cast<const clang::StringLiteral>(casted_self);
2388 return reinterpret_cast<const ZigClangStringLiteral *>(cast);
2389}
2390
23852391const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *self, unsigned i) {
23862392 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
23872393 const clang::Expr *result = casted->getInit(i);
......@@ -2394,6 +2400,16 @@ const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListEx
23942400 return reinterpret_cast<const ZigClangExpr *>(result);
23952401}
23962402
2403bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *self) {
2404 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2405 return casted->hasArrayFiller();
2406}
2407
2408bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *self) {
2409 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
2410 return casted->isStringLiteralInit();
2411}
2412
23972413const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self) {
23982414 auto casted = reinterpret_cast<const clang::InitListExpr *>(self);
23992415 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,
12201220 ZigClangAPFloat **result, const struct ZigClangASTContext *ctx);
12211221ZIG_EXTERN_C bool ZigClangExpr_EvaluateAsConstantExpr(const struct ZigClangExpr *,
12221222 struct ZigClangExprEvalResult *, ZigClangExpr_ConstantExprKind, const struct ZigClangASTContext *);
1223ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangExpr_castToStringLiteral(const struct ZigClangExpr *self);
12231224
12241225ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getInit(const ZigClangInitListExpr *, unsigned);
12251226ZIG_EXTERN_C const ZigClangExpr *ZigClangInitListExpr_getArrayFiller(const ZigClangInitListExpr *);
1227ZIG_EXTERN_C bool ZigClangInitListExpr_hasArrayFiller(const ZigClangInitListExpr *);
1228ZIG_EXTERN_C bool ZigClangInitListExpr_isStringLiteralInit(const ZigClangInitListExpr *);
12261229ZIG_EXTERN_C unsigned ZigClangInitListExpr_getNumInits(const ZigClangInitListExpr *);
12271230ZIG_EXTERN_C const ZigClangFieldDecl *ZigClangInitListExpr_getInitializedFieldInUnion(const ZigClangInitListExpr *self);
12281231
stage1/zig.h+619-349
......@@ -253,97 +253,6 @@ typedef char bool;
253253#define zig_concat(lhs, rhs) lhs##rhs
254254#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
255255
256#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
257#include <stdatomic.h>
258#define zig_atomic(type) _Atomic(type)
259#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
260#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
261#define zig_atomicrmw_xchg(obj, arg, order, type) atomic_exchange_explicit (obj, arg, order)
262#define zig_atomicrmw_add(obj, arg, order, type) atomic_fetch_add_explicit (obj, arg, order)
263#define zig_atomicrmw_sub(obj, arg, order, type) atomic_fetch_sub_explicit (obj, arg, order)
264#define zig_atomicrmw_or(obj, arg, order, type) atomic_fetch_or_explicit (obj, arg, order)
265#define zig_atomicrmw_xor(obj, arg, order, type) atomic_fetch_xor_explicit (obj, arg, order)
266#define zig_atomicrmw_and(obj, arg, order, type) atomic_fetch_and_explicit (obj, arg, order)
267#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand (obj, arg, order)
268#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
269#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
270#define zig_atomic_store(obj, arg, order, type) atomic_store_explicit (obj, arg, order)
271#define zig_atomic_load(obj, order, type) atomic_load_explicit (obj, order)
272#define zig_fence(order) atomic_thread_fence(order)
273#elif defined(__GNUC__)
274#define memory_order_relaxed __ATOMIC_RELAXED
275#define memory_order_consume __ATOMIC_CONSUME
276#define memory_order_acquire __ATOMIC_ACQUIRE
277#define memory_order_release __ATOMIC_RELEASE
278#define memory_order_acq_rel __ATOMIC_ACQ_REL
279#define memory_order_seq_cst __ATOMIC_SEQ_CST
280#define zig_atomic(type) type
281#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)
282#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)
283#define zig_atomicrmw_xchg(obj, arg, order, type) __atomic_exchange_n(obj, arg, order)
284#define zig_atomicrmw_add(obj, arg, order, type) __atomic_fetch_add (obj, arg, order)
285#define zig_atomicrmw_sub(obj, arg, order, type) __atomic_fetch_sub (obj, arg, order)
286#define zig_atomicrmw_or(obj, arg, order, type) __atomic_fetch_or (obj, arg, order)
287#define zig_atomicrmw_xor(obj, arg, order, type) __atomic_fetch_xor (obj, arg, order)
288#define zig_atomicrmw_and(obj, arg, order, type) __atomic_fetch_and (obj, arg, order)
289#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand(obj, arg, order)
290#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
291#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
292#define zig_atomic_store(obj, arg, order, type) __atomic_store_n (obj, arg, order)
293#define zig_atomic_load(obj, order, type) __atomic_load_n (obj, order)
294#define zig_fence(order) __atomic_thread_fence(order)
295#elif _MSC_VER && (_M_IX86 || _M_X64)
296#define memory_order_relaxed 0
297#define memory_order_consume 1
298#define memory_order_acquire 2
299#define memory_order_release 3
300#define memory_order_acq_rel 4
301#define memory_order_seq_cst 5
302#define zig_atomic(type) type
303#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_expand_concat(zig_msvc_cmpxchg_, type)(obj, &(expected), desired)
304#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_cmpxchg_strong(obj, expected, desired, succ, fail, type)
305#define zig_atomicrmw_xchg(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xchg_, type)(obj, arg)
306#define zig_atomicrmw_add(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_add_, type)(obj, arg)
307#define zig_atomicrmw_sub(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_sub_, type)(obj, arg)
308#define zig_atomicrmw_or(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_or_, type)(obj, arg)
309#define zig_atomicrmw_xor(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xor_, type)(obj, arg)
310#define zig_atomicrmw_and(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_and_, type)(obj, arg)
311#define zig_atomicrmw_nand(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_nand_, type)(obj, arg)
312#define zig_atomicrmw_min(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_min_, type)(obj, arg)
313#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)
314#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)
315#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)
316#if _M_X64
317#define zig_fence(order) __faststorefence()
318#else
319#define zig_fence(order) zig_msvc_atomic_barrier()
320#endif
321
322// TODO: _MSC_VER && (_M_ARM || _M_ARM64)
323#else
324#define memory_order_relaxed 0
325#define memory_order_consume 1
326#define memory_order_acquire 2
327#define memory_order_release 3
328#define memory_order_acq_rel 4
329#define memory_order_seq_cst 5
330#define zig_atomic(type) type
331#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_unimplemented()
332#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_unimplemented()
333#define zig_atomicrmw_xchg(obj, arg, order, type) zig_unimplemented()
334#define zig_atomicrmw_add(obj, arg, order, type) zig_unimplemented()
335#define zig_atomicrmw_sub(obj, arg, order, type) zig_unimplemented()
336#define zig_atomicrmw_or(obj, arg, order, type) zig_unimplemented()
337#define zig_atomicrmw_xor(obj, arg, order, type) zig_unimplemented()
338#define zig_atomicrmw_and(obj, arg, order, type) zig_unimplemented()
339#define zig_atomicrmw_nand(obj, arg, order, type) zig_unimplemented()
340#define zig_atomicrmw_min(obj, arg, order, type) zig_unimplemented()
341#define zig_atomicrmw_max(obj, arg, order, type) zig_unimplemented()
342#define zig_atomic_store(obj, arg, order, type) zig_unimplemented()
343#define zig_atomic_load(obj, order, type) zig_unimplemented()
344#define zig_fence(order) zig_unimplemented()
345#endif
346
347256#if __STDC_VERSION__ >= 201112L
348257#define zig_noreturn _Noreturn
349258#elif zig_has_attribute(noreturn) || defined(zig_gnuc)
......@@ -502,15 +411,6 @@ typedef ptrdiff_t intptr_t;
502411
503412#endif
504413
505#define zig_make_small_i8(val) INT8_C(val)
506#define zig_make_small_u8(val) UINT8_C(val)
507#define zig_make_small_i16(val) INT16_C(val)
508#define zig_make_small_u16(val) UINT16_C(val)
509#define zig_make_small_i32(val) INT32_C(val)
510#define zig_make_small_u32(val) UINT32_C(val)
511#define zig_make_small_i64(val) INT64_C(val)
512#define zig_make_small_u64(val) UINT64_C(val)
513
514414#define zig_minInt_i8 INT8_MIN
515415#define zig_maxInt_i8 INT8_MAX
516416#define zig_minInt_u8 UINT8_C(0)
......@@ -534,24 +434,24 @@ typedef ptrdiff_t intptr_t;
534434#define zig_minInt_u(w, bits) zig_intLimit(u, w, min, bits)
535435#define zig_maxInt_u(w, bits) zig_intLimit(u, w, max, bits)
536436
537#define zig_int_operator(Type, RhsType, operation, operator) \
437#define zig_operator(Type, RhsType, operation, operator) \
538438 static inline Type zig_##operation(Type lhs, RhsType rhs) { \
539439 return lhs operator rhs; \
540440 }
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)
545445#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, >>) \
555455\
556456 static inline int##w##_t zig_shr_i##w(int##w##_t lhs, uint8_t rhs) { \
557457 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;
576476 ? val | zig_minInt_i(w, bits) : val & zig_maxInt_i(w, bits); \
577477 } \
578478\
579 zig_int_basic_operator(uint##w##_t, div_floor_u##w, /) \
479 zig_basic_operator(uint##w##_t, div_floor_u##w, /) \
580480\
581481 static inline int##w##_t zig_div_floor_i##w(int##w##_t lhs, int##w##_t rhs) { \
582482 return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < INT##w##_C(0)); \
583483 } \
584484\
585 zig_int_basic_operator(uint##w##_t, mod_u##w, %) \
485 zig_basic_operator(uint##w##_t, mod_u##w, %) \
586486\
587487 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
588488 int##w##_t rem = lhs % rhs; \
......@@ -1253,8 +1153,8 @@ typedef signed __int128 zig_i128;
12531153#define zig_lo_u128(val) ((uint64_t)((val) >> 0))
12541154#define zig_hi_i128(val) (( int64_t)((val) >> 64))
12551155#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))
12581158#define zig_cmp_int128(Type) \
12591159 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
12601160 return (lhs > rhs) - (lhs < rhs); \
......@@ -1288,8 +1188,8 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
12881188#define zig_lo_u128(val) ((val).lo)
12891189#define zig_hi_i128(val) ((val).hi)
12901190#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)
12931193#define zig_cmp_int128(Type) \
12941194 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
12951195 return (lhs.hi == rhs.hi) \
......@@ -1303,9 +1203,6 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
13031203
13041204#endif /* zig_has_int128 */
13051205
1306#define zig_make_small_u128(val) zig_make_u128(0, val)
1307#define zig_make_small_i128(val) zig_make_i128((val) < 0 ? -INT64_C(1) : INT64_C(0), val)
1308
13091206#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
13101207#define zig_maxInt_u128 zig_make_u128(zig_maxInt_u64, zig_maxInt_u64)
13111208#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) {
14661363}
14671364
14681365static 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)));
14701367}
14711368
14721369zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
14731370static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
14741371 return __udivti3(lhs, rhs);
1475};
1372}
14761373
14771374zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
14781375static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) {
14791376 return __divti3(lhs, rhs);
1480};
1377}
14811378
14821379zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
14831380static 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) {
15031400#define zig_div_floor_u128 zig_div_trunc_u128
15041401#define zig_mod_u128 zig_rem_u128
15051402
1506static inline zig_u128 zig_nand_u128(zig_u128 lhs, zig_u128 rhs) {
1507 return zig_not_u128(zig_and_u128(lhs, rhs), 128);
1508}
1509
15101403static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) {
15111404 return zig_cmp_u128(lhs, rhs) < INT32_C(0) ? lhs : rhs;
15121405}
......@@ -1538,7 +1431,7 @@ static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
15381431}
15391432
15401433static 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);
15421435}
15431436
15441437static 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) {
15461439}
15471440
15481441static 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);
15501443}
15511444
15521445static 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) {
15541447}
15551448
15561449static 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);
15581451}
15591452
15601453static 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) {
15621455}
15631456
15641457static 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);
15661459}
15671460
15681461#if zig_has_int128
......@@ -1697,7 +1590,7 @@ static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8
16971590
16981591static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
16991592 *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)));
17011594 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
17021595 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
17031596}
......@@ -1711,7 +1604,7 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
17111604
17121605static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
17131606 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;
17151608 return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
17161609}
17171610
......@@ -1755,7 +1648,7 @@ static inline uint8_t zig_clz_u128(zig_u128 val, uint8_t bits) {
17551648}
17561649
17571650static 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);
17591652}
17601653
17611654static 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) {
17641657}
17651658
17661659static 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);
17681661}
17691662
17701663static 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) {
17731666}
17741667
17751668static 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);
17771670}
17781671
17791672static 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) {
17881681}
17891682
17901683static 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));
17921685}
17931686
17941687static 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) {
17981691}
17991692
18001693static 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));
18021695}
18031696
18041697/* ========================== Big Integer Support =========================== */
......@@ -1972,6 +1865,243 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign
19721865 return 0;
19731866}
19741867
1868static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1869 uint8_t *res_bytes = res;
1870 const uint8_t *lhs_bytes = lhs;
1871 const uint8_t *rhs_bytes = rhs;
1872 uint16_t byte_offset = 0;
1873 uint16_t remaining_bytes = zig_int_bytes(bits);
1874 (void)is_signed;
1875
1876 while (remaining_bytes >= 128 / CHAR_BIT) {
1877 zig_u128 res_limb;
1878 zig_u128 lhs_limb;
1879 zig_u128 rhs_limb;
1880
1881 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1882 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1883 res_limb = zig_and_u128(lhs_limb, rhs_limb);
1884 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1885
1886 remaining_bytes -= 128 / CHAR_BIT;
1887 byte_offset += 128 / CHAR_BIT;
1888 }
1889
1890 while (remaining_bytes >= 64 / CHAR_BIT) {
1891 uint64_t res_limb;
1892 uint64_t lhs_limb;
1893 uint64_t rhs_limb;
1894
1895 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1896 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1897 res_limb = zig_and_u64(lhs_limb, rhs_limb);
1898 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1899
1900 remaining_bytes -= 64 / CHAR_BIT;
1901 byte_offset += 64 / CHAR_BIT;
1902 }
1903
1904 while (remaining_bytes >= 32 / CHAR_BIT) {
1905 uint32_t res_limb;
1906 uint32_t lhs_limb;
1907 uint32_t rhs_limb;
1908
1909 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1910 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1911 res_limb = zig_and_u32(lhs_limb, rhs_limb);
1912 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1913
1914 remaining_bytes -= 32 / CHAR_BIT;
1915 byte_offset += 32 / CHAR_BIT;
1916 }
1917
1918 while (remaining_bytes >= 16 / CHAR_BIT) {
1919 uint16_t res_limb;
1920 uint16_t lhs_limb;
1921 uint16_t rhs_limb;
1922
1923 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1924 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1925 res_limb = zig_and_u16(lhs_limb, rhs_limb);
1926 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1927
1928 remaining_bytes -= 16 / CHAR_BIT;
1929 byte_offset += 16 / CHAR_BIT;
1930 }
1931
1932 while (remaining_bytes >= 8 / CHAR_BIT) {
1933 uint8_t res_limb;
1934 uint8_t lhs_limb;
1935 uint8_t rhs_limb;
1936
1937 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1938 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1939 res_limb = zig_and_u8(lhs_limb, rhs_limb);
1940 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1941
1942 remaining_bytes -= 8 / CHAR_BIT;
1943 byte_offset += 8 / CHAR_BIT;
1944 }
1945}
1946
1947static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1948 uint8_t *res_bytes = res;
1949 const uint8_t *lhs_bytes = lhs;
1950 const uint8_t *rhs_bytes = rhs;
1951 uint16_t byte_offset = 0;
1952 uint16_t remaining_bytes = zig_int_bytes(bits);
1953 (void)is_signed;
1954
1955 while (remaining_bytes >= 128 / CHAR_BIT) {
1956 zig_u128 res_limb;
1957 zig_u128 lhs_limb;
1958 zig_u128 rhs_limb;
1959
1960 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1961 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1962 res_limb = zig_or_u128(lhs_limb, rhs_limb);
1963 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1964
1965 remaining_bytes -= 128 / CHAR_BIT;
1966 byte_offset += 128 / CHAR_BIT;
1967 }
1968
1969 while (remaining_bytes >= 64 / CHAR_BIT) {
1970 uint64_t res_limb;
1971 uint64_t lhs_limb;
1972 uint64_t rhs_limb;
1973
1974 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1975 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1976 res_limb = zig_or_u64(lhs_limb, rhs_limb);
1977 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1978
1979 remaining_bytes -= 64 / CHAR_BIT;
1980 byte_offset += 64 / CHAR_BIT;
1981 }
1982
1983 while (remaining_bytes >= 32 / CHAR_BIT) {
1984 uint32_t res_limb;
1985 uint32_t lhs_limb;
1986 uint32_t rhs_limb;
1987
1988 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1989 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1990 res_limb = zig_or_u32(lhs_limb, rhs_limb);
1991 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
1992
1993 remaining_bytes -= 32 / CHAR_BIT;
1994 byte_offset += 32 / CHAR_BIT;
1995 }
1996
1997 while (remaining_bytes >= 16 / CHAR_BIT) {
1998 uint16_t res_limb;
1999 uint16_t lhs_limb;
2000 uint16_t rhs_limb;
2001
2002 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2003 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2004 res_limb = zig_or_u16(lhs_limb, rhs_limb);
2005 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2006
2007 remaining_bytes -= 16 / CHAR_BIT;
2008 byte_offset += 16 / CHAR_BIT;
2009 }
2010
2011 while (remaining_bytes >= 8 / CHAR_BIT) {
2012 uint8_t res_limb;
2013 uint8_t lhs_limb;
2014 uint8_t rhs_limb;
2015
2016 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2017 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2018 res_limb = zig_or_u8(lhs_limb, rhs_limb);
2019 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2020
2021 remaining_bytes -= 8 / CHAR_BIT;
2022 byte_offset += 8 / CHAR_BIT;
2023 }
2024}
2025
2026static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
2027 uint8_t *res_bytes = res;
2028 const uint8_t *lhs_bytes = lhs;
2029 const uint8_t *rhs_bytes = rhs;
2030 uint16_t byte_offset = 0;
2031 uint16_t remaining_bytes = zig_int_bytes(bits);
2032 (void)is_signed;
2033
2034 while (remaining_bytes >= 128 / CHAR_BIT) {
2035 zig_u128 res_limb;
2036 zig_u128 lhs_limb;
2037 zig_u128 rhs_limb;
2038
2039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2040 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2041 res_limb = zig_xor_u128(lhs_limb, rhs_limb);
2042 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2043
2044 remaining_bytes -= 128 / CHAR_BIT;
2045 byte_offset += 128 / CHAR_BIT;
2046 }
2047
2048 while (remaining_bytes >= 64 / CHAR_BIT) {
2049 uint64_t res_limb;
2050 uint64_t lhs_limb;
2051 uint64_t rhs_limb;
2052
2053 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2054 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2055 res_limb = zig_xor_u64(lhs_limb, rhs_limb);
2056 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2057
2058 remaining_bytes -= 64 / CHAR_BIT;
2059 byte_offset += 64 / CHAR_BIT;
2060 }
2061
2062 while (remaining_bytes >= 32 / CHAR_BIT) {
2063 uint32_t res_limb;
2064 uint32_t lhs_limb;
2065 uint32_t rhs_limb;
2066
2067 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2068 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2069 res_limb = zig_xor_u32(lhs_limb, rhs_limb);
2070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2071
2072 remaining_bytes -= 32 / CHAR_BIT;
2073 byte_offset += 32 / CHAR_BIT;
2074 }
2075
2076 while (remaining_bytes >= 16 / CHAR_BIT) {
2077 uint16_t res_limb;
2078 uint16_t lhs_limb;
2079 uint16_t rhs_limb;
2080
2081 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2082 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2083 res_limb = zig_xor_u16(lhs_limb, rhs_limb);
2084 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2085
2086 remaining_bytes -= 16 / CHAR_BIT;
2087 byte_offset += 16 / CHAR_BIT;
2088 }
2089
2090 while (remaining_bytes >= 8 / CHAR_BIT) {
2091 uint8_t res_limb;
2092 uint8_t lhs_limb;
2093 uint8_t rhs_limb;
2094
2095 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2096 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2097 res_limb = zig_xor_u8(lhs_limb, rhs_limb);
2098 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
2099
2100 remaining_bytes -= 8 / CHAR_BIT;
2101 byte_offset += 8 / CHAR_BIT;
2102 }
2103}
2104
19752105static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
19762106 uint8_t *res_bytes = res;
19772107 const uint8_t *lhs_bytes = lhs;
......@@ -2827,24 +2957,20 @@ long double __cdecl nanl(char const* input);
28272957#endif
28282958
28292959#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)
28352964#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
28362965#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)
28432971#endif
28442972
28452973#define zig_has_f16 1
2846#define zig_bitSizeOf_f16 16
2847typedef uint16_t zig_repr_f16;
28482974#define zig_libc_name_f16(name) __##name##h
28492975#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
28502976#if FLT_MANT_DIG == 11
......@@ -2854,10 +2980,6 @@ typedef float zig_f16;
28542980typedef double zig_f16;
28552981#define zig_make_f16(fp, repr) fp
28562982#elif LDBL_MANT_DIG == 11
2857#define zig_bitSizeOf_c_longdouble 16
2858#ifndef ZIG_TARGET_ABI_MSVC
2859typedef zig_repr_f16 zig_repr_c_longdouble;
2860#endif
28612983typedef long double zig_f16;
28622984#define zig_make_f16(fp, repr) fp##l
28632985#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))
......@@ -2869,8 +2991,8 @@ typedef __fp16 zig_f16;
28692991#else
28702992#undef zig_has_f16
28712993#define zig_has_f16 0
2872#define zig_bitSizeOf_repr_f16 16
2873typedef zig_repr_f16 zig_f16;
2994#define zig_repr_f16 u16
2995typedef uint16_t zig_f16;
28742996#define zig_make_f16(fp, repr) repr
28752997#undef zig_make_special_f16
28762998#define zig_make_special_f16(sign, name, arg, repr) repr
......@@ -2878,15 +3000,12 @@ typedef zig_repr_f16 zig_f16;
28783000#define zig_init_special_f16(sign, name, arg, repr) repr
28793001#endif
28803002#if __APPLE__ && (defined(__i386__) || defined(__x86_64__))
2881typedef zig_repr_f16 zig_compiler_rt_f16;
3003typedef uint16_t zig_compiler_rt_f16;
28823004#else
28833005typedef zig_f16 zig_compiler_rt_f16;
28843006#endif
2885#define zig_compiler_rt_abbrev_zig_compiler_rt_f16 zig_compiler_rt_abbrev_zig_f16
28863007
28873008#define zig_has_f32 1
2888#define zig_bitSizeOf_f32 32
2889typedef uint32_t zig_repr_f32;
28903009#define zig_libc_name_f32(name) name##f
28913010#if _MSC_VER
28923011#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;
29003019typedef double zig_f32;
29013020#define zig_make_f32(fp, repr) fp
29023021#elif LDBL_MANT_DIG == 24
2903#define zig_bitSizeOf_c_longdouble 32
2904#ifndef ZIG_TARGET_ABI_MSVC
2905typedef zig_repr_f32 zig_repr_c_longdouble;
2906#endif
29073022typedef long double zig_f32;
29083023#define zig_make_f32(fp, repr) fp##l
29093024#elif FLT32_MANT_DIG == 24
......@@ -2912,8 +3027,8 @@ typedef _Float32 zig_f32;
29123027#else
29133028#undef zig_has_f32
29143029#define zig_has_f32 0
2915#define zig_bitSizeOf_repr_f32 32
2916typedef zig_repr_f32 zig_f32;
3030#define zig_repr_f32 u32
3031ypedef uint32_t zig_f32;
29173032#define zig_make_f32(fp, repr) repr
29183033#undef zig_make_special_f32
29193034#define zig_make_special_f32(sign, name, arg, repr) repr
......@@ -2922,20 +3037,12 @@ typedef zig_repr_f32 zig_f32;
29223037#endif
29233038
29243039#define zig_has_f64 1
2925#define zig_bitSizeOf_f64 64
2926typedef uint64_t zig_repr_f64;
29273040#define zig_libc_name_f64(name) name
29283041#if _MSC_VER
2929#ifdef ZIG_TARGET_ABI_MSVC
2930#define zig_bitSizeOf_c_longdouble 64
2931#ifndef ZIG_TARGET_ABI_MSVC
2932typedef zig_repr_f64 zig_repr_c_longdouble;
2933#endif
2934#endif
29353042#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
2936#else /* _MSC_VER */
3043#else
29373044#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
2938#endif /* _MSC_VER */
3045#endif
29393046#if FLT_MANT_DIG == 53
29403047typedef float zig_f64;
29413048#define zig_make_f64(fp, repr) fp##f
......@@ -2943,10 +3050,6 @@ typedef float zig_f64;
29433050typedef double zig_f64;
29443051#define zig_make_f64(fp, repr) fp
29453052#elif LDBL_MANT_DIG == 53
2946#define zig_bitSizeOf_c_longdouble 64
2947#ifndef ZIG_TARGET_ABI_MSVC
2948typedef zig_repr_f64 zig_repr_c_longdouble;
2949#endif
29503053typedef long double zig_f64;
29513054#define zig_make_f64(fp, repr) fp##l
29523055#elif FLT64_MANT_DIG == 53
......@@ -2958,8 +3061,8 @@ typedef _Float32x zig_f64;
29583061#else
29593062#undef zig_has_f64
29603063#define zig_has_f64 0
2961#define zig_bitSizeOf_repr_f64 64
2962typedef zig_repr_f64 zig_f64;
3064#define zig_repr_f64 u64
3065typedef uint64_t zig_f64;
29633066#define zig_make_f64(fp, repr) repr
29643067#undef zig_make_special_f64
29653068#define zig_make_special_f64(sign, name, arg, repr) repr
......@@ -2968,8 +3071,6 @@ typedef zig_repr_f64 zig_f64;
29683071#endif
29693072
29703073#define zig_has_f80 1
2971#define zig_bitSizeOf_f80 80
2972typedef zig_u128 zig_repr_f80;
29733074#define zig_libc_name_f80(name) __##name##x
29743075#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
29753076#if FLT_MANT_DIG == 64
......@@ -2979,10 +3080,6 @@ typedef float zig_f80;
29793080typedef double zig_f80;
29803081#define zig_make_f80(fp, repr) fp
29813082#elif LDBL_MANT_DIG == 64
2982#define zig_bitSizeOf_c_longdouble 80
2983#ifndef ZIG_TARGET_ABI_MSVC
2984typedef zig_repr_f80 zig_repr_c_longdouble;
2985#endif
29863083typedef long double zig_f80;
29873084#define zig_make_f80(fp, repr) fp##l
29883085#elif FLT80_MANT_DIG == 64
......@@ -2997,8 +3094,8 @@ typedef __float80 zig_f80;
29973094#else
29983095#undef zig_has_f80
29993096#define zig_has_f80 0
3000#define zig_bitSizeOf_repr_f80 128
3001typedef zig_repr_f80 zig_f80;
3097#define zig_repr_f80 u128
3098typedef zig_u128 zig_f80;
30023099#define zig_make_f80(fp, repr) repr
30033100#undef zig_make_special_f80
30043101#define zig_make_special_f80(sign, name, arg, repr) repr
......@@ -3007,8 +3104,6 @@ typedef zig_repr_f80 zig_f80;
30073104#endif
30083105
30093106#define zig_has_f128 1
3010#define zig_bitSizeOf_f128 128
3011typedef zig_u128 zig_repr_f128;
30123107#define zig_libc_name_f128(name) name##q
30133108#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
30143109#if FLT_MANT_DIG == 113
......@@ -3018,10 +3113,6 @@ typedef float zig_f128;
30183113typedef double zig_f128;
30193114#define zig_make_f128(fp, repr) fp
30203115#elif LDBL_MANT_DIG == 113
3021#define zig_bitSizeOf_c_longdouble 128
3022#ifndef ZIG_TARGET_ABI_MSVC
3023typedef zig_repr_f128 zig_repr_c_longdouble;
3024#endif
30253116typedef long double zig_f128;
30263117#define zig_make_f128(fp, repr) fp##l
30273118#elif FLT128_MANT_DIG == 113
......@@ -3038,50 +3129,49 @@ typedef __float128 zig_f128;
30383129#else
30393130#undef zig_has_f128
30403131#define zig_has_f128 0
3041#define zig_bitSizeOf_repr_f128 128
3042typedef zig_repr_f128 zig_f128;
3043#define zig_make_f128(fp, repr) repr
30443132#undef zig_make_special_f128
3045#define zig_make_special_f128(sign, name, arg, repr) repr
30463133#undef zig_init_special_f128
3134#if __APPLE__ || defined(__aarch64__)
3135typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_v2u64;
3136zig_basic_operator(zig_v2u64, xor_v2u64, ^)
3137#define zig_repr_f128 v2u64
3138typedef zig_v2u64 zig_f128;
3139#define zig_make_f128_zig_make_u128(hi, lo) (zig_f128){ lo, hi }
3140#define zig_make_f128_zig_init_u128 zig_make_f128_zig_make_u128
3141#define zig_make_f128(fp, repr) zig_make_f128_##repr
3142#define zig_make_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3143#define zig_init_special_f128(sign, name, arg, repr) zig_make_f128_##repr
3144#else
3145#define zig_repr_f128 u128
3146typedef zig_u128 zig_f128;
3147#define zig_make_f128(fp, repr) repr
3148#define zig_make_special_f128(sign, name, arg, repr) repr
30473149#define zig_init_special_f128(sign, name, arg, repr) repr
30483150#endif
3151#endif
30493152
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 */
30563155typedef zig_f64 zig_c_longdouble;
3057typedef zig_repr_f64 zig_repr_c_longdouble;
3156#elif _MSC_VER && !defined(ZIG_TARGET_ABI_MSVC)
3157/* Emulate gnu abi on an msvc compiler */
3158typedef zig_f128 zig_c_longdouble;
30583159#else
3160/* Target and compiler abi match */
30593161typedef long double zig_c_longdouble;
30603162#endif
30613163
3062#else /* zig_bitSizeOf_c_longdouble */
3063
3064#define zig_has_c_longdouble 0
3065#define zig_bitSizeOf_repr_c_longdouble 128
3066typedef zig_f128 zig_c_longdouble;
3067typedef zig_repr_f128 zig_repr_c_longdouble;
3068
3069#endif /* zig_bitSizeOf_c_longdouble */
3070
3071#if !zig_has_float_builtins
3072#define zig_float_from_repr(Type) \
3073 static inline zig_##Type zig_float_from_repr_##Type(zig_repr_##Type repr) { \
3164#define zig_bitCast_float(Type, ReprType) \
3165 static inline zig_##Type zig_bitCast_##Type(ReprType repr) { \
30743166 zig_##Type result; \
30753167 memcpy(&result, &repr, sizeof(result)); \
30763168 return result; \
30773169 }
3078
3079zig_float_from_repr(f16)
3080zig_float_from_repr(f32)
3081zig_float_from_repr(f64)
3082zig_float_from_repr(f80)
3083zig_float_from_repr(f128)
3084#endif
3170zig_bitCast_float(f16, uint16_t)
3171zig_bitCast_float(f32, uint32_t)
3172zig_bitCast_float(f64, uint64_t)
3173zig_bitCast_float(f80, zig_u128)
3174zig_bitCast_float(f128, zig_u128)
30853175
30863176#define zig_cast_f16 (zig_f16)
30873177#define zig_cast_f32 (zig_f32)
......@@ -3095,44 +3185,53 @@ zig_float_from_repr(f128)
30953185#define zig_cast_f128 (zig_f128)
30963186#endif
30973187
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);
3101zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f32, 2)
3102zig_convert_builtin(zig_compiler_rt_f16, trunc, zig_f64, 2)
3103zig_convert_builtin(zig_f16, trunc, zig_f80, 2)
3104zig_convert_builtin(zig_f16, trunc, zig_f128, 2)
3105zig_convert_builtin(zig_f32, extend, zig_compiler_rt_f16, 2)
3106zig_convert_builtin(zig_f32, trunc, zig_f64, 2)
3107zig_convert_builtin(zig_f32, trunc, zig_f80, 2)
3108zig_convert_builtin(zig_f32, trunc, zig_f128, 2)
3109zig_convert_builtin(zig_f64, extend, zig_compiler_rt_f16, 2)
3110zig_convert_builtin(zig_f64, extend, zig_f32, 2)
3111zig_convert_builtin(zig_f64, trunc, zig_f80, 2)
3112zig_convert_builtin(zig_f64, trunc, zig_f128, 2)
3113zig_convert_builtin(zig_f80, extend, zig_f16, 2)
3114zig_convert_builtin(zig_f80, extend, zig_f32, 2)
3115zig_convert_builtin(zig_f80, extend, zig_f64, 2)
3116zig_convert_builtin(zig_f80, trunc, zig_f128, 2)
3117zig_convert_builtin(zig_f128, extend, zig_f16, 2)
3118zig_convert_builtin(zig_f128, extend, zig_f32, 2)
3119zig_convert_builtin(zig_f128, extend, zig_f64, 2)
3120zig_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 }
3202zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f32, zig_f32, 2)
3203zig_convert_builtin(zig_compiler_rt_f16, zig_f16, trunc, zig_f64, zig_f64, 2)
3204zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f80, zig_f80, 2)
3205zig_convert_builtin(zig_f16, zig_f16, trunc, zig_f128, zig_f128, 2)
3206zig_convert_builtin(zig_f32, zig_f32, extend, zig_compiler_rt_f16, zig_f16, 2)
3207zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f64, zig_f64, 2)
3208zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f80, zig_f80, 2)
3209zig_convert_builtin(zig_f32, zig_f32, trunc, zig_f128, zig_f128, 2)
3210zig_convert_builtin(zig_f64, zig_f64, extend, zig_compiler_rt_f16, zig_f16, 2)
3211zig_convert_builtin(zig_f64, zig_f64, extend, zig_f32, zig_f32, 2)
3212zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f80, zig_f80, 2)
3213zig_convert_builtin(zig_f64, zig_f64, trunc, zig_f128, zig_f128, 2)
3214zig_convert_builtin(zig_f80, zig_f80, extend, zig_f16, zig_f16, 2)
3215zig_convert_builtin(zig_f80, zig_f80, extend, zig_f32, zig_f32, 2)
3216zig_convert_builtin(zig_f80, zig_f80, extend, zig_f64, zig_f64, 2)
3217zig_convert_builtin(zig_f80, zig_f80, trunc, zig_f128, zig_f128, 2)
3218zig_convert_builtin(zig_f128, zig_f128, extend, zig_f16, zig_f16, 2)
3219zig_convert_builtin(zig_f128, zig_f128, extend, zig_f32, zig_f32, 2)
3220zig_convert_builtin(zig_f128, zig_f128, extend, zig_f64, zig_f64, 2)
3221zig_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) \
31333227 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); \
31353229 }
3230zig_float_negate_builtin(16, , UINT16_C(1) << 15 )
3231zig_float_negate_builtin(32, , UINT32_C(1) << 31 )
3232zig_float_negate_builtin(64, , UINT64_C(1) << 63 )
3233zig_float_negate_builtin(80, zig_make_u128, (UINT64_C(1) << 15, UINT64_C(0)))
3234zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
31363235
31373236#define zig_float_less_builtin_0(Type, operation) \
31383237 zig_extern int32_t zig_expand_concat(zig_expand_concat(__##operation, \
......@@ -3164,19 +3263,18 @@ zig_convert_builtin(zig_f128, extend, zig_f80, 2)
31643263 }
31653264
31663265#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, ) \
31803278 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
31813279 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
31823280 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
......@@ -3224,9 +3322,238 @@ zig_float_builtins(64)
32243322zig_float_builtins(80)
32253323zig_float_builtins(128)
32263324
3325/* ============================ Atomics Support ============================= */
3326
3327/* Note that atomics should be implemented as macros because most
3328 compilers silently discard runtime atomic order information. */
3329
3330/* Define fallback implementations first that can later be undef'd on compilers with builtin support. */
3331/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */
3332#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \
3333 zig_##Type zig_atomicrmw_expected; \
3334 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3335 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3336 res = zig_atomicrmw_expected; \
3337} while (0)
3338#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \
3339 zig_##Type zig_atomicrmw_expected; \
3340 zig_##Type zig_atomicrmw_desired; \
3341 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3342 do { \
3343 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3344 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3345 res = zig_atomicrmw_expected; \
3346} while (0)
3347#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \
3348 zig_##Type zig_atomicrmw_expected; \
3349 zig_##Type zig_atomicrmw_desired; \
3350 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3351 do { \
3352 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3353 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3354 res = zig_atomicrmw_expected; \
3355} while (0)
3356#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \
3357 zig_##Type zig_atomicrmw_expected; \
3358 zig_##Type zig_atomicrmw_desired; \
3359 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3360 do { \
3361 zig_atomicrmw_desired = zig_libc_name_##Type(fmin)(zig_atomicrmw_expected, arg); \
3362 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3363 res = zig_atomicrmw_expected; \
3364} while (0)
3365#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \
3366 zig_##Type zig_atomicrmw_expected; \
3367 zig_##Type zig_atomicrmw_desired; \
3368 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3369 do { \
3370 zig_atomicrmw_desired = zig_libc_name_##Type(fmax)(zig_atomicrmw_expected, arg); \
3371 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3372 res = zig_atomicrmw_expected; \
3373} while (0)
3374
3375#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \
3376 zig_##Type zig_atomicrmw_expected; \
3377 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3378 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3379 res = zig_atomicrmw_expected; \
3380} while (0)
3381#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \
3382 zig_##Type zig_atomicrmw_expected; \
3383 zig_##Type zig_atomicrmw_desired; \
3384 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3385 do { \
3386 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3387 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3388 res = zig_atomicrmw_expected; \
3389} while (0)
3390#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \
3391 zig_##Type zig_atomicrmw_expected; \
3392 zig_##Type zig_atomicrmw_desired; \
3393 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3394 do { \
3395 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3396 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3397 res = zig_atomicrmw_expected; \
3398} while (0)
3399#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \
3400 zig_##Type zig_atomicrmw_expected; \
3401 zig_##Type zig_atomicrmw_desired; \
3402 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3403 do { \
3404 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \
3405 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3406 res = zig_atomicrmw_expected; \
3407} while (0)
3408#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \
3409 zig_##Type zig_atomicrmw_expected; \
3410 zig_##Type zig_atomicrmw_desired; \
3411 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3412 do { \
3413 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \
3414 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3415 res = zig_atomicrmw_expected; \
3416} while (0)
3417#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \
3418 zig_##Type zig_atomicrmw_expected; \
3419 zig_##Type zig_atomicrmw_desired; \
3420 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3421 do { \
3422 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \
3423 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3424 res = zig_atomicrmw_expected; \
3425} while (0)
3426#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \
3427 zig_##Type zig_atomicrmw_expected; \
3428 zig_##Type zig_atomicrmw_desired; \
3429 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3430 do { \
3431 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \
3432 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3433 res = zig_atomicrmw_expected; \
3434} while (0)
3435#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \
3436 zig_##Type zig_atomicrmw_expected; \
3437 zig_##Type zig_atomicrmw_desired; \
3438 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3439 do { \
3440 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \
3441 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3442 res = zig_atomicrmw_expected; \
3443} while (0)
3444#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \
3445 zig_##Type zig_atomicrmw_expected; \
3446 zig_##Type zig_atomicrmw_desired; \
3447 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3448 do { \
3449 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \
3450 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3451 res = zig_atomicrmw_expected; \
3452} while (0)
3453
3454#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
3455#include <stdatomic.h>
3456typedef enum memory_order zig_memory_order;
3457#define zig_atomic(Type) _Atomic(Type)
3458#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
3459#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
3460#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = atomic_exchange_explicit (obj, arg, order)
3461#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = atomic_fetch_add_explicit (obj, arg, order)
3462#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = atomic_fetch_sub_explicit (obj, arg, order)
3463#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = atomic_fetch_or_explicit (obj, arg, order)
3464#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = atomic_fetch_xor_explicit (obj, arg, order)
3465#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = atomic_fetch_and_explicit (obj, arg, order)
3466#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
3467#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
3468#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
3469#define zig_atomic_store( obj, arg, order, Type, ReprType) atomic_store_explicit (obj, arg, order)
3470#define zig_atomic_load(res, obj, order, Type, ReprType) res = atomic_load_explicit (obj, order)
3471#undef zig_atomicrmw_xchg_float
3472#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3473#undef zig_atomicrmw_add_float
3474#define zig_atomicrmw_add_float zig_atomicrmw_add
3475#undef zig_atomicrmw_sub_float
3476#define zig_atomicrmw_sub_float zig_atomicrmw_sub
3477#define zig_fence(order) atomic_thread_fence(order)
3478#elif defined(__GNUC__)
3479typedef int zig_memory_order;
3480#define memory_order_relaxed __ATOMIC_RELAXED
3481#define memory_order_consume __ATOMIC_CONSUME
3482#define memory_order_acquire __ATOMIC_ACQUIRE
3483#define memory_order_release __ATOMIC_RELEASE
3484#define memory_order_acq_rel __ATOMIC_ACQ_REL
3485#define memory_order_seq_cst __ATOMIC_SEQ_CST
3486#define zig_atomic(Type) Type
3487#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)
3488#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), true, succ, fail)
3489#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, &(arg), &(res), order)
3490#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_add (obj, arg, order)
3491#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_sub (obj, arg, order)
3492#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_or (obj, arg, order)
3493#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_xor (obj, arg, order)
3494#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_and (obj, arg, order)
3495#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
3496#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
3497#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
3498#define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, &(arg), order)
3499#define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order)
3500#undef zig_atomicrmw_xchg_float
3501#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3502#define zig_fence(order) __atomic_thread_fence(order)
3503#elif _MSC_VER && (_M_IX86 || _M_X64)
3504#define memory_order_relaxed 0
3505#define memory_order_consume 1
3506#define memory_order_acquire 2
3507#define memory_order_release 3
3508#define memory_order_acq_rel 4
3509#define memory_order_seq_cst 5
3510#define zig_atomic(Type) Type
3511#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)
3512#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType)
3513#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xchg_##Type(obj, arg)
3514#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_add_ ##Type(obj, arg)
3515#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_sub_ ##Type(obj, arg)
3516#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_or_ ##Type(obj, arg)
3517#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xor_ ##Type(obj, arg)
3518#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_and_ ##Type(obj, arg)
3519#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_nand_##Type(obj, arg)
3520#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_min_ ##Type(obj, arg)
3521#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg)
3522#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg)
3523#define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##Type(obj)
3524#if _M_X64
3525#define zig_fence(order) __faststorefence()
3526#else
3527#define zig_fence(order) zig_msvc_atomic_barrier()
3528#endif
3529/* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */
3530#else
3531#define memory_order_relaxed 0
3532#define memory_order_consume 1
3533#define memory_order_acquire 2
3534#define memory_order_release 3
3535#define memory_order_acq_rel 4
3536#define memory_order_seq_cst 5
3537#define zig_atomic(Type) Type
3538#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3539#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3540#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3541#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3542#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3543#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3544#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3545#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3546#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3547#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3548#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
3549#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable
3550#define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable
3551#define zig_fence(order) zig_fence_unavailable
3552#endif
3553
32273554#if _MSC_VER && (_M_IX86 || _M_X64)
32283555
3229// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64
3556/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
32303557
32313558#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \
32323559 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)
33163643zig_msvc_atomics(i64, int64_t, __int64, 64)
33173644#endif
33183645
3319#define zig_msvc_flt_atomics(Type, ReprType, suffix) \
3646#define zig_msvc_flt_atomics(Type, SigType, suffix) \
33203647 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; \
33243651 bool success; \
33253652 memcpy(&comparand, expected, sizeof(comparand)); \
33263653 memcpy(&exchange, &desired, sizeof(exchange)); \
3327 initial = _InterlockedCompareExchange##suffix((ReprType volatile*)obj, exchange, comparand); \
3654 initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, exchange, comparand); \
33283655 success = initial == comparand; \
33293656 if (!success) memcpy(expected, &initial, sizeof(*expected)); \
33303657 return success; \
33313658 } \
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) { \
33353665 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); \
33383667 memcpy(&result, &initial, sizeof(result)); \
33393668 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; \
33623669 }
3363
33643670zig_msvc_flt_atomics(f32, long, )
33653671#if _M_X64
33663672zig_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
34213727static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
34223728 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);
34233729}
3424
3425#define zig_msvc_atomics_128xchg(Type) \
3426 static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3427 bool success = false; \
3428 zig_##Type prev; \
3429 while (!success) { \
3430 prev = *obj; \
3431 success = zig_msvc_cmpxchg_##Type(obj, &prev, value); \
3432 } \
3433 return prev; \
3434 }
3435
3436zig_msvc_atomics_128xchg(u128)
3437zig_msvc_atomics_128xchg(i128)
3438
3439#define zig_msvc_atomics_128op(Type, operation) \
3440 static inline zig_##Type zig_msvc_atomicrmw_##operation##_##Type(zig_##Type volatile* obj, zig_##Type value) { \
3441 bool success = false; \
3442 zig_##Type new; \
3443 zig_##Type prev; \
3444 while (!success) { \
3445 prev = *obj; \
3446 new = zig_##operation##_##Type(prev, value); \
3447 success = zig_msvc_cmpxchg_##Type(obj, &prev, new); \
3448 } \
3449 return prev; \
3450 }
3451
3452zig_msvc_atomics_128op(u128, add)
3453zig_msvc_atomics_128op(u128, sub)
3454zig_msvc_atomics_128op(u128, or)
3455zig_msvc_atomics_128op(u128, xor)
3456zig_msvc_atomics_128op(u128, and)
3457zig_msvc_atomics_128op(u128, nand)
3458zig_msvc_atomics_128op(u128, min)
3459zig_msvc_atomics_128op(u128, max)
34603730#endif /* _M_IX86 */
34613731
34623732#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" {
401401}
402402
403403test "explicit cast from integer to error type" {
404 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
405404 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
406405 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
407406 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" {
16491649 };
16501650 try expect(S.value == 1);
16511651}
1652
1653test "@inComptime" {
1654 const S = struct {
1655 fn inComptime() bool {
1656 return @inComptime();
1657 }
1658 };
1659 try expectEqual(false, @inComptime());
1660 try expectEqual(true, comptime @inComptime());
1661 try expectEqual(false, S.inComptime());
1662 try expectEqual(true, comptime S.inComptime());
1663}
test/behavior/fn.zig+17
......@@ -455,6 +455,23 @@ test "method call with optional and error union first param" {
455455 try s.errUnion();
456456}
457457
458test "method call with optional pointer first param" {
459 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
460 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
461
462 const S = struct {
463 x: i32 = 1234,
464
465 fn method(s: ?*@This()) !void {
466 try expect(s.?.x == 1234);
467 }
468 };
469 var s: S = .{};
470 try s.method();
471 const s_ptr = &s;
472 try s_ptr.method();
473}
474
458475test "using @ptrCast on function pointers" {
459476 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
460477 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" {
486486}
487487
488488test "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
493492
494493 const some_opaque = opaque {};
495494 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 {
2929//
3030// :9:1: error: union initializer must initialize one field
3131// :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
3333// :14:31: note: additional initializer here
3434// :1:12: note: union declared here
3535// :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
3737// :22:31: note: additional initializer here
3838// :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 {
2121// backend=stage2
2222// target=native
2323//
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
2525// :9:24: error: arrays must be passed by reference to variadic function
2626// :13:24: error: cannot pass 'u48' to variadic function
2727// :13:24: note: only integers with power of two bits are extern compatible
test/cases/safety/pointer casting to null function pointer.zig created+23
......@@ -0,0 +1,23 @@
1const std = @import("std");
2
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
4 _ = stack_trace;
5 if (std.mem.eql(u8, message, "cast causes pointer to be null")) {
6 std.process.exit(0);
7 }
8 std.process.exit(1);
9}
10
11fn getNullPtr() ?*const anyopaque {
12 return null;
13}
14pub fn main() !void {
15 const null_ptr: ?*const anyopaque = getNullPtr();
16 const required_ptr: *align(1) const fn() void = @ptrCast(*align(1) const fn() void, null_ptr);
17 _ = required_ptr;
18 return error.TestFailed;
19}
20
21// run
22// backend=llvm
23// target=native
test/tests.zig+6
......@@ -1040,6 +1040,12 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10401040 });
10411041 compile_c.addIncludePath("lib"); // for zig.h
10421042 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 }
10431049 if (test_target.link_libc == false) {
10441050 compile_c.subsystem = .Console;
10451051 compile_c.linkSystemLibrary("kernel32");
test/translate_c.zig+6
......@@ -3956,4 +3956,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
39563956 \\ .name = "foo",
39573957 \\});
39583958 });
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 });
39593965}