@zigc/lib 0.15.1 → 0.15.2-test.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +19 -0
  2. package/build-web/fuzz.zig +6 -6
  3. package/build-web/time_report.zig +14 -13
  4. package/compiler/reduce/Walk.zig +10 -9
  5. package/compiler/reduce.zig +19 -20
  6. package/compiler/resinator/compile.zig +1 -1
  7. package/compiler_rt/arm.zig +1 -1
  8. package/init/build.zig +1 -1
  9. package/libc/include/generic-glibc/arpa/inet.h +3 -0
  10. package/libc/musl/src/fenv/loongarch64/fenv-sf.c +3 -0
  11. package/package.json +1 -1
  12. package/std/Build/Step/Compile.zig +20 -1
  13. package/std/Build/Step/TranslateC.zig +6 -0
  14. package/std/Build/WebServer.zig +1 -1
  15. package/std/Build.zig +4 -1
  16. package/std/Io/Reader/Limited.zig +44 -0
  17. package/std/Io/Reader.zig +128 -28
  18. package/std/Io/Writer.zig +31 -6
  19. package/std/Target.zig +8 -0
  20. package/std/Thread.zig +3 -4
  21. package/std/c.zig +87 -26
  22. package/std/crypto/aes_ocb.zig +32 -3
  23. package/std/crypto/tls/Client.zig +19 -8
  24. package/std/debug.zig +1 -1
  25. package/std/fs/Dir.zig +2 -1
  26. package/std/fs/File.zig +105 -104
  27. package/std/http/Client.zig +3 -2
  28. package/std/json/static.zig +3 -3
  29. package/std/math/big/int.zig +3 -4
  30. package/std/math/powi.zig +1 -0
  31. package/std/mem/Allocator.zig +3 -1
  32. package/std/mem.zig +3 -1
  33. package/std/net.zig +3 -2
  34. package/std/os/linux/bpf.zig +2 -2
  35. package/std/os/linux/powerpc.zig +74 -12
  36. package/std/os/linux/powerpc64.zig +74 -12
  37. package/std/os/linux.zig +7 -2
  38. package/std/os/uefi/protocol/service_binding.zig +1 -1
  39. package/std/os/uefi/tables.zig +1 -1
  40. package/std/pie.zig +1 -1
  41. package/std/posix.zig +6 -4
  42. package/std/process/Child.zig +5 -1
  43. package/std/process.zig +16 -2
  44. package/std/sort/pdq.zig +48 -1
  45. package/std/testing.zig +60 -0
  46. package/std/zig/llvm/BitcodeReader.zig +5 -1
  47. package/std/zig/system/linux.zig +1 -4
  48. package/std/zig/system.zig +3 -2
  49. package/std/zon/parse.zig +1 -0
  50. package/ubsan_rt.zig +3 -3
package/std/fs/File.zig CHANGED
@@ -1242,7 +1242,7 @@ pub const Reader = struct {
1242
1242
  pub fn seekBy(r: *Reader, offset: i64) Reader.SeekError!void {
1243
1243
  switch (r.mode) {
1244
1244
  .positional, .positional_reading => {
1245
- setPosAdjustingBuffer(r, @intCast(@as(i64, @intCast(r.pos)) + offset));
1245
+ setLogicalPos(r, @intCast(@as(i64, @intCast(logicalPos(r))) + offset));
1246
1246
  },
1247
1247
  .streaming, .streaming_reading => {
1248
1248
  if (posix.SEEK == void) {
@@ -1251,7 +1251,7 @@ pub const Reader = struct {
1251
1251
  }
1252
1252
  const seek_err = r.seek_err orelse e: {
1253
1253
  if (posix.lseek_CUR(r.file.handle, offset)) |_| {
1254
- setPosAdjustingBuffer(r, @intCast(@as(i64, @intCast(r.pos)) + offset));
1254
+ setLogicalPos(r, @intCast(@as(i64, @intCast(logicalPos(r))) + offset));
1255
1255
  return;
1256
1256
  } else |err| {
1257
1257
  r.seek_err = err;
@@ -1275,16 +1275,17 @@ pub const Reader = struct {
1275
1275
  pub fn seekTo(r: *Reader, offset: u64) Reader.SeekError!void {
1276
1276
  switch (r.mode) {
1277
1277
  .positional, .positional_reading => {
1278
- setPosAdjustingBuffer(r, offset);
1278
+ setLogicalPos(r, offset);
1279
1279
  },
1280
1280
  .streaming, .streaming_reading => {
1281
- if (offset >= r.pos) return Reader.seekBy(r, @intCast(offset - r.pos));
1281
+ const logical_pos = logicalPos(r);
1282
+ if (offset >= logical_pos) return Reader.seekBy(r, @intCast(offset - logical_pos));
1282
1283
  if (r.seek_err) |err| return err;
1283
1284
  posix.lseek_SET(r.file.handle, offset) catch |err| {
1284
1285
  r.seek_err = err;
1285
1286
  return err;
1286
1287
  };
1287
- setPosAdjustingBuffer(r, offset);
1288
+ setLogicalPos(r, offset);
1288
1289
  },
1289
1290
  .failure => return r.seek_err.?,
1290
1291
  }
@@ -1294,7 +1295,7 @@ pub const Reader = struct {
1294
1295
  return r.pos - r.interface.bufferedLen();
1295
1296
  }
1296
1297
 
1297
- fn setPosAdjustingBuffer(r: *Reader, offset: u64) void {
1298
+ fn setLogicalPos(r: *Reader, offset: u64) void {
1298
1299
  const logical_pos = logicalPos(r);
1299
1300
  if (offset < logical_pos or offset >= r.pos) {
1300
1301
  r.interface.seek = 0;
@@ -1322,13 +1323,15 @@ pub const Reader = struct {
1322
1323
  },
1323
1324
  .positional_reading => {
1324
1325
  const dest = limit.slice(try w.writableSliceGreedy(1));
1325
- const n = try readPositional(r, dest);
1326
+ var data: [1][]u8 = .{dest};
1327
+ const n = try readVecPositional(r, &data);
1326
1328
  w.advance(n);
1327
1329
  return n;
1328
1330
  },
1329
1331
  .streaming_reading => {
1330
1332
  const dest = limit.slice(try w.writableSliceGreedy(1));
1331
- const n = try readStreaming(r, dest);
1333
+ var data: [1][]u8 = .{dest};
1334
+ const n = try readVecStreaming(r, &data);
1332
1335
  w.advance(n);
1333
1336
  return n;
1334
1337
  },
@@ -1339,92 +1342,98 @@ pub const Reader = struct {
1339
1342
  fn readVec(io_reader: *std.Io.Reader, data: [][]u8) std.Io.Reader.Error!usize {
1340
1343
  const r: *Reader = @alignCast(@fieldParentPtr("interface", io_reader));
1341
1344
  switch (r.mode) {
1342
- .positional, .positional_reading => {
1343
- if (is_windows) {
1344
- // Unfortunately, `ReadFileScatter` cannot be used since it
1345
- // requires page alignment.
1346
- if (io_reader.seek == io_reader.end) {
1347
- io_reader.seek = 0;
1348
- io_reader.end = 0;
1349
- }
1350
- const first = data[0];
1351
- if (first.len >= io_reader.buffer.len - io_reader.end) {
1352
- return readPositional(r, first);
1353
- } else {
1354
- io_reader.end += try readPositional(r, io_reader.buffer[io_reader.end..]);
1355
- return 0;
1356
- }
1357
- }
1358
- var iovecs_buffer: [max_buffers_len]posix.iovec = undefined;
1359
- const dest_n, const data_size = try io_reader.writableVectorPosix(&iovecs_buffer, data);
1360
- const dest = iovecs_buffer[0..dest_n];
1361
- assert(dest[0].len > 0);
1362
- const n = posix.preadv(r.file.handle, dest, r.pos) catch |err| switch (err) {
1363
- error.Unseekable => {
1364
- r.mode = r.mode.toStreaming();
1365
- const pos = r.pos;
1366
- if (pos != 0) {
1367
- r.pos = 0;
1368
- r.seekBy(@intCast(pos)) catch {
1369
- r.mode = .failure;
1370
- return error.ReadFailed;
1371
- };
1372
- }
1373
- return 0;
1374
- },
1375
- else => |e| {
1376
- r.err = e;
1345
+ .positional, .positional_reading => return readVecPositional(r, data),
1346
+ .streaming, .streaming_reading => return readVecStreaming(r, data),
1347
+ .failure => return error.ReadFailed,
1348
+ }
1349
+ }
1350
+
1351
+ fn readVecPositional(r: *Reader, data: [][]u8) std.Io.Reader.Error!usize {
1352
+ const io_reader = &r.interface;
1353
+ if (is_windows) {
1354
+ // Unfortunately, `ReadFileScatter` cannot be used since it
1355
+ // requires page alignment.
1356
+ if (io_reader.seek == io_reader.end) {
1357
+ io_reader.seek = 0;
1358
+ io_reader.end = 0;
1359
+ }
1360
+ const first = data[0];
1361
+ if (first.len >= io_reader.buffer.len - io_reader.end) {
1362
+ return readPositional(r, first);
1363
+ } else {
1364
+ io_reader.end += try readPositional(r, io_reader.buffer[io_reader.end..]);
1365
+ return 0;
1366
+ }
1367
+ }
1368
+ var iovecs_buffer: [max_buffers_len]posix.iovec = undefined;
1369
+ const dest_n, const data_size = try io_reader.writableVectorPosix(&iovecs_buffer, data);
1370
+ const dest = iovecs_buffer[0..dest_n];
1371
+ assert(dest[0].len > 0);
1372
+ const n = posix.preadv(r.file.handle, dest, r.pos) catch |err| switch (err) {
1373
+ error.Unseekable => {
1374
+ r.mode = r.mode.toStreaming();
1375
+ const pos = r.pos;
1376
+ if (pos != 0) {
1377
+ r.pos = 0;
1378
+ r.seekBy(@intCast(pos)) catch {
1379
+ r.mode = .failure;
1377
1380
  return error.ReadFailed;
1378
- },
1379
- };
1380
- if (n == 0) {
1381
- r.size = r.pos;
1382
- return error.EndOfStream;
1383
- }
1384
- r.pos += n;
1385
- if (n > data_size) {
1386
- io_reader.end += n - data_size;
1387
- return data_size;
1381
+ };
1388
1382
  }
1389
- return n;
1383
+ return 0;
1390
1384
  },
1391
- .streaming, .streaming_reading => {
1392
- if (is_windows) {
1393
- // Unfortunately, `ReadFileScatter` cannot be used since it
1394
- // requires page alignment.
1395
- if (io_reader.seek == io_reader.end) {
1396
- io_reader.seek = 0;
1397
- io_reader.end = 0;
1398
- }
1399
- const first = data[0];
1400
- if (first.len >= io_reader.buffer.len - io_reader.end) {
1401
- return readPositional(r, first);
1402
- } else {
1403
- io_reader.end += try readPositional(r, io_reader.buffer[io_reader.end..]);
1404
- return 0;
1405
- }
1406
- }
1407
- var iovecs_buffer: [max_buffers_len]posix.iovec = undefined;
1408
- const dest_n, const data_size = try io_reader.writableVectorPosix(&iovecs_buffer, data);
1409
- const dest = iovecs_buffer[0..dest_n];
1410
- assert(dest[0].len > 0);
1411
- const n = posix.readv(r.file.handle, dest) catch |err| {
1412
- r.err = err;
1413
- return error.ReadFailed;
1414
- };
1415
- if (n == 0) {
1416
- r.size = r.pos;
1417
- return error.EndOfStream;
1418
- }
1419
- r.pos += n;
1420
- if (n > data_size) {
1421
- io_reader.end += n - data_size;
1422
- return data_size;
1423
- }
1424
- return n;
1385
+ else => |e| {
1386
+ r.err = e;
1387
+ return error.ReadFailed;
1425
1388
  },
1426
- .failure => return error.ReadFailed,
1389
+ };
1390
+ if (n == 0) {
1391
+ r.size = r.pos;
1392
+ return error.EndOfStream;
1393
+ }
1394
+ r.pos += n;
1395
+ if (n > data_size) {
1396
+ io_reader.end += n - data_size;
1397
+ return data_size;
1427
1398
  }
1399
+ return n;
1400
+ }
1401
+
1402
+ fn readVecStreaming(r: *Reader, data: [][]u8) std.Io.Reader.Error!usize {
1403
+ const io_reader = &r.interface;
1404
+ if (is_windows) {
1405
+ // Unfortunately, `ReadFileScatter` cannot be used since it
1406
+ // requires page alignment.
1407
+ if (io_reader.seek == io_reader.end) {
1408
+ io_reader.seek = 0;
1409
+ io_reader.end = 0;
1410
+ }
1411
+ const first = data[0];
1412
+ if (first.len >= io_reader.buffer.len - io_reader.end) {
1413
+ return readStreaming(r, first);
1414
+ } else {
1415
+ io_reader.end += try readStreaming(r, io_reader.buffer[io_reader.end..]);
1416
+ return 0;
1417
+ }
1418
+ }
1419
+ var iovecs_buffer: [max_buffers_len]posix.iovec = undefined;
1420
+ const dest_n, const data_size = try io_reader.writableVectorPosix(&iovecs_buffer, data);
1421
+ const dest = iovecs_buffer[0..dest_n];
1422
+ assert(dest[0].len > 0);
1423
+ const n = posix.readv(r.file.handle, dest) catch |err| {
1424
+ r.err = err;
1425
+ return error.ReadFailed;
1426
+ };
1427
+ if (n == 0) {
1428
+ r.size = r.pos;
1429
+ return error.EndOfStream;
1430
+ }
1431
+ r.pos += n;
1432
+ if (n > data_size) {
1433
+ io_reader.end += n - data_size;
1434
+ return data_size;
1435
+ }
1436
+ return n;
1428
1437
  }
1429
1438
 
1430
1439
  fn discard(io_reader: *std.Io.Reader, limit: std.Io.Limit) std.Io.Reader.Error!usize {
@@ -1493,7 +1502,7 @@ pub const Reader = struct {
1493
1502
  }
1494
1503
  }
1495
1504
 
1496
- pub fn readPositional(r: *Reader, dest: []u8) std.Io.Reader.Error!usize {
1505
+ fn readPositional(r: *Reader, dest: []u8) std.Io.Reader.Error!usize {
1497
1506
  const n = r.file.pread(dest, r.pos) catch |err| switch (err) {
1498
1507
  error.Unseekable => {
1499
1508
  r.mode = r.mode.toStreaming();
@@ -1520,7 +1529,7 @@ pub const Reader = struct {
1520
1529
  return n;
1521
1530
  }
1522
1531
 
1523
- pub fn readStreaming(r: *Reader, dest: []u8) std.Io.Reader.Error!usize {
1532
+ fn readStreaming(r: *Reader, dest: []u8) std.Io.Reader.Error!usize {
1524
1533
  const n = r.file.read(dest) catch |err| {
1525
1534
  r.err = err;
1526
1535
  return error.ReadFailed;
@@ -1533,14 +1542,6 @@ pub const Reader = struct {
1533
1542
  return n;
1534
1543
  }
1535
1544
 
1536
- pub fn read(r: *Reader, dest: []u8) std.Io.Reader.Error!usize {
1537
- switch (r.mode) {
1538
- .positional, .positional_reading => return readPositional(r, dest),
1539
- .streaming, .streaming_reading => return readStreaming(r, dest),
1540
- .failure => return error.ReadFailed,
1541
- }
1542
- }
1543
-
1544
1545
  pub fn atEnd(r: *Reader) bool {
1545
1546
  // Even if stat fails, size is set when end is encountered.
1546
1547
  const size = r.size orelse return false;
@@ -1783,7 +1784,7 @@ pub const Writer = struct {
1783
1784
  ) std.Io.Writer.FileError!usize {
1784
1785
  const reader_buffered = file_reader.interface.buffered();
1785
1786
  if (reader_buffered.len >= @intFromEnum(limit))
1786
- return sendFileBuffered(io_w, file_reader, reader_buffered);
1787
+ return sendFileBuffered(io_w, file_reader, limit.slice(reader_buffered));
1787
1788
  const writer_buffered = io_w.buffered();
1788
1789
  const file_limit = @intFromEnum(limit) - reader_buffered.len;
1789
1790
  const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w));
@@ -1855,7 +1856,7 @@ pub const Writer = struct {
1855
1856
  return error.EndOfStream;
1856
1857
  }
1857
1858
  const consumed = io_w.consume(@intCast(sbytes));
1858
- file_reader.seekTo(file_reader.pos + consumed) catch return error.ReadFailed;
1859
+ file_reader.seekBy(@intCast(consumed)) catch return error.ReadFailed;
1859
1860
  return consumed;
1860
1861
  }
1861
1862
 
@@ -1916,7 +1917,7 @@ pub const Writer = struct {
1916
1917
  return error.EndOfStream;
1917
1918
  }
1918
1919
  const consumed = io_w.consume(@bitCast(len));
1919
- file_reader.seekTo(file_reader.pos + consumed) catch return error.ReadFailed;
1920
+ file_reader.seekBy(@intCast(consumed)) catch return error.ReadFailed;
1920
1921
  return consumed;
1921
1922
  }
1922
1923
 
@@ -1967,7 +1968,7 @@ pub const Writer = struct {
1967
1968
 
1968
1969
  const copy_file_range = switch (native_os) {
1969
1970
  .freebsd => std.os.freebsd.copy_file_range,
1970
- .linux => if (std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 })) std.os.linux.wrapped.copy_file_range else {},
1971
+ .linux => std.os.linux.wrapped.copy_file_range,
1971
1972
  else => {},
1972
1973
  };
1973
1974
  if (@TypeOf(copy_file_range) != void) cfr: {
@@ -2049,7 +2050,7 @@ pub const Writer = struct {
2049
2050
  reader_buffered: []const u8,
2050
2051
  ) std.Io.Writer.FileError!usize {
2051
2052
  const n = try drain(io_w, &.{reader_buffered}, 1);
2052
- file_reader.seekTo(file_reader.pos + n) catch return error.ReadFailed;
2053
+ file_reader.seekBy(@intCast(n)) catch return error.ReadFailed;
2053
2054
  return n;
2054
2055
  }
2055
2056
 
@@ -1375,7 +1375,7 @@ pub const basic_authorization = struct {
1375
1375
  var buf: [max_user_len + 1 + max_password_len]u8 = undefined;
1376
1376
  var w: Writer = .fixed(&buf);
1377
1377
  const user: Uri.Component = uri.user orelse .empty;
1378
- const password: Uri.Component = uri.user orelse .empty;
1378
+ const password: Uri.Component = uri.password orelse .empty;
1379
1379
  user.formatUser(&w) catch unreachable;
1380
1380
  w.writeByte(':') catch unreachable;
1381
1381
  password.formatPassword(&w) catch unreachable;
@@ -1797,9 +1797,10 @@ pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult {
1797
1797
 
1798
1798
  if (options.payload) |payload| {
1799
1799
  req.transfer_encoding = .{ .content_length = payload.len };
1800
- var body = try req.sendBody(&.{});
1800
+ var body = try req.sendBodyUnflushed(&.{});
1801
1801
  try body.writer.writeAll(payload);
1802
1802
  try body.end();
1803
+ try req.connection.?.flush();
1803
1804
  } else {
1804
1805
  try req.sendBodiless();
1805
1806
  }
@@ -567,8 +567,8 @@ pub fn innerParseFromValue(
567
567
  switch (source) {
568
568
  .float => |f| {
569
569
  if (@round(f) != f) return error.InvalidNumber;
570
- if (f > std.math.maxInt(T)) return error.Overflow;
571
- if (f < std.math.minInt(T)) return error.Overflow;
570
+ if (f > @as(@TypeOf(f), @floatFromInt(std.math.maxInt(T)))) return error.Overflow;
571
+ if (f < @as(@TypeOf(f), @floatFromInt(std.math.minInt(T)))) return error.Overflow;
572
572
  return @as(T, @intFromFloat(f));
573
573
  },
574
574
  .integer => |i| {
@@ -770,7 +770,7 @@ fn sliceToInt(comptime T: type, slice: []const u8) !T {
770
770
  // Try to coerce a float to an integer.
771
771
  const float = try std.fmt.parseFloat(f128, slice);
772
772
  if (@round(float) != float) return error.InvalidNumber;
773
- if (float > std.math.maxInt(T) or float < std.math.minInt(T)) return error.Overflow;
773
+ if (float > @as(f128, @floatFromInt(std.math.maxInt(T))) or float < @as(f128, @floatFromInt(std.math.minInt(T)))) return error.Overflow;
774
774
  return @as(T, @intCast(@as(i128, @intFromFloat(float))));
775
775
  }
776
776
 
@@ -786,11 +786,10 @@ pub const Mutable = struct {
786
786
  assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing
787
787
 
788
788
  if (a.limbs.len == 1 and b.limbs.len == 1) {
789
- const ov = @mulWithOverflow(a.limbs[0], b.limbs[0]);
790
- rma.limbs[0] = ov[0];
791
- if (ov[1] == 0) {
789
+ rma.limbs[0], const overflow_bit = @mulWithOverflow(a.limbs[0], b.limbs[0]);
790
+ if (overflow_bit == 0) {
792
791
  rma.len = 1;
793
- rma.positive = (a.positive == b.positive);
792
+ rma.positive = (a.positive == b.positive) or rma.limbs[0] == 0;
794
793
  return;
795
794
  }
796
795
  }
package/std/math/powi.zig CHANGED
@@ -13,6 +13,7 @@ const testing = std.testing;
13
13
  /// Errors:
14
14
  /// - Overflow: Integer overflow or Infinity
15
15
  /// - Underflow: Absolute value of result smaller than 1
16
+ ///
16
17
  /// Edge case rules ordered by precedence:
17
18
  /// - powi(T, x, 0) = 1 unless T is i1, i0, u0
18
19
  /// - powi(T, 0, x) = 0 when x > 0
@@ -358,8 +358,10 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {
358
358
  return mem.bytesAsSlice(T, new_memory);
359
359
  }
360
360
 
361
- /// This function requests a new byte size for an existing allocation, which
361
+ /// This function requests a new size for an existing allocation, which
362
362
  /// can be larger, smaller, or the same size as the old memory allocation.
363
+ /// The result is an array of `new_n` items of the same type as the existing
364
+ /// allocation.
363
365
  ///
364
366
  /// If `new_n` is 0, this is the same as `free` and it always succeeds.
365
367
  ///
package/std/mem.zig CHANGED
@@ -3785,6 +3785,7 @@ test rotate {
3785
3785
 
3786
3786
  /// Replace needle with replacement as many times as possible, writing to an output buffer which is assumed to be of
3787
3787
  /// appropriate size. Use replacementSize to calculate an appropriate buffer size.
3788
+ /// The `input` and `output` slices must not overlap.
3788
3789
  /// The needle must not be empty.
3789
3790
  /// Returns the number of replacements made.
3790
3791
  pub fn replace(comptime T: type, input: []const T, needle: []const T, replacement: []const T, output: []T) usize {
@@ -4484,7 +4485,8 @@ pub fn doNotOptimizeAway(val: anytype) void {
4484
4485
  } else doNotOptimizeAway(&val);
4485
4486
  },
4486
4487
  .float => {
4487
- if ((t.float.bits == 32 or t.float.bits == 64) and builtin.zig_backend != .stage2_c) {
4488
+ // https://github.com/llvm/llvm-project/issues/159200
4489
+ if ((t.float.bits == 32 or t.float.bits == 64) and builtin.zig_backend != .stage2_c and !builtin.cpu.arch.isLoongArch()) {
4488
4490
  asm volatile (""
4489
4491
  :
4490
4492
  : [_] "rm" (val),
package/std/net.zig CHANGED
@@ -1393,7 +1393,7 @@ fn parseHosts(
1393
1393
  br: *Io.Reader,
1394
1394
  ) error{ OutOfMemory, ReadFailed }!void {
1395
1395
  while (true) {
1396
- const line = br.takeDelimiterExclusive('\n') catch |err| switch (err) {
1396
+ const line = br.takeDelimiter('\n') catch |err| switch (err) {
1397
1397
  error.StreamTooLong => {
1398
1398
  // Skip lines that are too long.
1399
1399
  _ = br.discardDelimiterInclusive('\n') catch |e| switch (e) {
@@ -1403,7 +1403,8 @@ fn parseHosts(
1403
1403
  continue;
1404
1404
  },
1405
1405
  error.ReadFailed => return error.ReadFailed,
1406
- error.EndOfStream => break,
1406
+ } orelse {
1407
+ break; // end of stream
1407
1408
  };
1408
1409
  var split_it = mem.splitScalar(u8, line, '#');
1409
1410
  const no_comment_line = split_it.first();
@@ -642,7 +642,7 @@ pub const Insn = packed struct {
642
642
  .dst = @intFromEnum(dst),
643
643
  .src = @intFromEnum(src),
644
644
  .off = 0,
645
- .imm = @as(i32, @intCast(@as(u32, @truncate(imm)))),
645
+ .imm = @as(i32, @bitCast(@as(u32, @truncate(imm)))),
646
646
  };
647
647
  }
648
648
 
@@ -652,7 +652,7 @@ pub const Insn = packed struct {
652
652
  .dst = 0,
653
653
  .src = 0,
654
654
  .off = 0,
655
- .imm = @as(i32, @intCast(@as(u32, @truncate(imm >> 32)))),
655
+ .imm = @as(i32, @bitCast(@as(u32, @truncate(imm >> 32)))),
656
656
  };
657
657
  }
658
658
 
@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;
15
15
  const timespec = linux.timespec;
16
16
 
17
17
  pub fn syscall0(number: SYS) usize {
18
+ // r0 is both an input register and a clobber. musl and glibc achieve this with
19
+ // a "+" constraint, which isn't supported in Zig, so instead we separately list
20
+ // r0 as both an input and an output. (Listing it as an input and a clobber would
21
+ // cause the C backend to emit invalid code; see #25209.)
22
+ var r0_out: usize = undefined;
18
23
  return asm volatile (
19
24
  \\ sc
20
25
  \\ bns+ 1f
21
26
  \\ neg 3, 3
22
27
  \\ 1:
23
28
  : [ret] "={r3}" (-> usize),
29
+ [r0_out] "={r0}" (r0_out),
24
30
  : [number] "{r0}" (@intFromEnum(number)),
25
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
31
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
26
32
  }
27
33
 
28
34
  pub fn syscall1(number: SYS, arg1: usize) usize {
35
+ // r0 is both an input and a clobber.
36
+ var r0_out: usize = undefined;
29
37
  return asm volatile (
30
38
  \\ sc
31
39
  \\ bns+ 1f
32
40
  \\ neg 3, 3
33
41
  \\ 1:
34
42
  : [ret] "={r3}" (-> usize),
43
+ [r0_out] "={r0}" (r0_out),
35
44
  : [number] "{r0}" (@intFromEnum(number)),
36
45
  [arg1] "{r3}" (arg1),
37
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
46
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
38
47
  }
39
48
 
40
49
  pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
50
+ // These registers are both inputs and clobbers.
51
+ var r0_out: usize = undefined;
52
+ var r4_out: usize = undefined;
41
53
  return asm volatile (
42
54
  \\ sc
43
55
  \\ bns+ 1f
44
56
  \\ neg 3, 3
45
57
  \\ 1:
46
58
  : [ret] "={r3}" (-> usize),
59
+ [r0_out] "={r0}" (r0_out),
60
+ [r4_out] "={r4}" (r4_out),
47
61
  : [number] "{r0}" (@intFromEnum(number)),
48
62
  [arg1] "{r3}" (arg1),
49
63
  [arg2] "{r4}" (arg2),
50
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
64
+ : .{ .memory = true, .cr0 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
51
65
  }
52
66
 
53
67
  pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
68
+ // These registers are both inputs and clobbers.
69
+ var r0_out: usize = undefined;
70
+ var r4_out: usize = undefined;
71
+ var r5_out: usize = undefined;
54
72
  return asm volatile (
55
73
  \\ sc
56
74
  \\ bns+ 1f
57
75
  \\ neg 3, 3
58
76
  \\ 1:
59
77
  : [ret] "={r3}" (-> usize),
78
+ [r0_out] "={r0}" (r0_out),
79
+ [r4_out] "={r4}" (r4_out),
80
+ [r5_out] "={r5}" (r5_out),
60
81
  : [number] "{r0}" (@intFromEnum(number)),
61
82
  [arg1] "{r3}" (arg1),
62
83
  [arg2] "{r4}" (arg2),
63
84
  [arg3] "{r5}" (arg3),
64
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
85
+ : .{ .memory = true, .cr0 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
65
86
  }
66
87
 
67
88
  pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
89
+ // These registers are both inputs and clobbers.
90
+ var r0_out: usize = undefined;
91
+ var r4_out: usize = undefined;
92
+ var r5_out: usize = undefined;
93
+ var r6_out: usize = undefined;
68
94
  return asm volatile (
69
95
  \\ sc
70
96
  \\ bns+ 1f
71
97
  \\ neg 3, 3
72
98
  \\ 1:
73
99
  : [ret] "={r3}" (-> usize),
100
+ [r0_out] "={r0}" (r0_out),
101
+ [r4_out] "={r4}" (r4_out),
102
+ [r5_out] "={r5}" (r5_out),
103
+ [r6_out] "={r6}" (r6_out),
74
104
  : [number] "{r0}" (@intFromEnum(number)),
75
105
  [arg1] "{r3}" (arg1),
76
106
  [arg2] "{r4}" (arg2),
77
107
  [arg3] "{r5}" (arg3),
78
108
  [arg4] "{r6}" (arg4),
79
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
109
+ : .{ .memory = true, .cr0 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
80
110
  }
81
111
 
82
112
  pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
113
+ // These registers are both inputs and clobbers.
114
+ var r0_out: usize = undefined;
115
+ var r4_out: usize = undefined;
116
+ var r5_out: usize = undefined;
117
+ var r6_out: usize = undefined;
118
+ var r7_out: usize = undefined;
83
119
  return asm volatile (
84
120
  \\ sc
85
121
  \\ bns+ 1f
86
122
  \\ neg 3, 3
87
123
  \\ 1:
88
124
  : [ret] "={r3}" (-> usize),
125
+ [r0_out] "={r0}" (r0_out),
126
+ [r4_out] "={r4}" (r4_out),
127
+ [r5_out] "={r5}" (r5_out),
128
+ [r6_out] "={r6}" (r6_out),
129
+ [r7_out] "={r7}" (r7_out),
89
130
  : [number] "{r0}" (@intFromEnum(number)),
90
131
  [arg1] "{r3}" (arg1),
91
132
  [arg2] "{r4}" (arg2),
92
133
  [arg3] "{r5}" (arg3),
93
134
  [arg4] "{r6}" (arg4),
94
135
  [arg5] "{r7}" (arg5),
95
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
136
+ : .{ .memory = true, .cr0 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
96
137
  }
97
138
 
98
139
  pub fn syscall6(
@@ -104,12 +145,25 @@ pub fn syscall6(
104
145
  arg5: usize,
105
146
  arg6: usize,
106
147
  ) usize {
148
+ // These registers are both inputs and clobbers.
149
+ var r0_out: usize = undefined;
150
+ var r4_out: usize = undefined;
151
+ var r5_out: usize = undefined;
152
+ var r6_out: usize = undefined;
153
+ var r7_out: usize = undefined;
154
+ var r8_out: usize = undefined;
107
155
  return asm volatile (
108
156
  \\ sc
109
157
  \\ bns+ 1f
110
158
  \\ neg 3, 3
111
159
  \\ 1:
112
160
  : [ret] "={r3}" (-> usize),
161
+ [r0_out] "={r0}" (r0_out),
162
+ [r4_out] "={r4}" (r4_out),
163
+ [r5_out] "={r5}" (r5_out),
164
+ [r6_out] "={r6}" (r6_out),
165
+ [r7_out] "={r7}" (r7_out),
166
+ [r8_out] "={r8}" (r8_out),
113
167
  : [number] "{r0}" (@intFromEnum(number)),
114
168
  [arg1] "{r3}" (arg1),
115
169
  [arg2] "{r4}" (arg2),
@@ -117,7 +171,7 @@ pub fn syscall6(
117
171
  [arg4] "{r6}" (arg4),
118
172
  [arg5] "{r7}" (arg5),
119
173
  [arg6] "{r8}" (arg6),
120
- : .{ .memory = true, .cr0 = true, .r0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
174
+ : .{ .memory = true, .cr0 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
121
175
  }
122
176
 
123
177
  pub fn clone() callconv(.naked) usize {
@@ -193,11 +247,19 @@ pub fn clone() callconv(.naked) usize {
193
247
  pub const restore = restore_rt;
194
248
 
195
249
  pub fn restore_rt() callconv(.naked) noreturn {
196
- asm volatile (
197
- \\ sc
198
- :
199
- : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
200
- : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true });
250
+ switch (@import("builtin").zig_backend) {
251
+ .stage2_c => asm volatile (
252
+ \\ li 0, %[number]
253
+ \\ sc
254
+ :
255
+ : [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
256
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true }),
257
+ else => _ = asm volatile (
258
+ \\ sc
259
+ :
260
+ : [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
261
+ : .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true }),
262
+ }
201
263
  }
202
264
 
203
265
  pub const F = struct {