@zigc/lib 0.16.0-dev.3121 → 0.16.0-dev.3132

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 (88) hide show
  1. package/c/math.zig +15 -13
  2. package/compiler/aro/backend/Ir/x86/Renderer.zig +3 -3
  3. package/compiler/build_runner.zig +1 -0
  4. package/compiler/resinator/compile.zig +2 -2
  5. package/compiler/test_runner.zig +191 -59
  6. package/fuzzer.zig +855 -307
  7. package/package.json +1 -1
  8. package/std/Build/Fuzz.zig +6 -19
  9. package/std/Build/Step/Run.zig +530 -68
  10. package/std/Build/abi.zig +39 -7
  11. package/std/Build.zig +3 -0
  12. package/std/Io/File/Reader.zig +3 -1
  13. package/std/Io/Kqueue.zig +2 -2
  14. package/std/Io.zig +2 -2
  15. package/std/bit_set.zig +22 -6
  16. package/std/compress/flate/Compress.zig +3 -3
  17. package/std/crypto/codecs/base64_hex_ct.zig +2 -2
  18. package/std/enums.zig +19 -25
  19. package/std/http/Client.zig +10 -6
  20. package/std/priority_dequeue.zig +13 -12
  21. package/std/priority_queue.zig +5 -4
  22. package/std/zig/Client.zig +8 -3
  23. package/std/zig/Server.zig +26 -0
  24. package/libc/mingw/complex/cabs.c +0 -48
  25. package/libc/mingw/complex/cabsf.c +0 -48
  26. package/libc/mingw/complex/cacos.c +0 -50
  27. package/libc/mingw/complex/cacosf.c +0 -50
  28. package/libc/mingw/complex/carg.c +0 -48
  29. package/libc/mingw/complex/cargf.c +0 -48
  30. package/libc/mingw/complex/casin.c +0 -50
  31. package/libc/mingw/complex/casinf.c +0 -50
  32. package/libc/mingw/complex/catan.c +0 -50
  33. package/libc/mingw/complex/catanf.c +0 -50
  34. package/libc/mingw/complex/ccos.c +0 -50
  35. package/libc/mingw/complex/ccosf.c +0 -50
  36. package/libc/mingw/complex/cexp.c +0 -48
  37. package/libc/mingw/complex/cexpf.c +0 -48
  38. package/libc/mingw/complex/cimag.c +0 -48
  39. package/libc/mingw/complex/cimagf.c +0 -48
  40. package/libc/mingw/complex/clog.c +0 -48
  41. package/libc/mingw/complex/clog10.c +0 -49
  42. package/libc/mingw/complex/clog10f.c +0 -49
  43. package/libc/mingw/complex/clogf.c +0 -48
  44. package/libc/mingw/complex/conj.c +0 -48
  45. package/libc/mingw/complex/conjf.c +0 -48
  46. package/libc/mingw/complex/cpow.c +0 -48
  47. package/libc/mingw/complex/cpowf.c +0 -48
  48. package/libc/mingw/complex/cproj.c +0 -48
  49. package/libc/mingw/complex/cprojf.c +0 -48
  50. package/libc/mingw/complex/creal.c +0 -48
  51. package/libc/mingw/complex/crealf.c +0 -48
  52. package/libc/mingw/complex/csin.c +0 -50
  53. package/libc/mingw/complex/csinf.c +0 -50
  54. package/libc/mingw/complex/csqrt.c +0 -48
  55. package/libc/mingw/complex/csqrtf.c +0 -48
  56. package/libc/mingw/complex/ctan.c +0 -50
  57. package/libc/mingw/complex/ctanf.c +0 -50
  58. package/libc/mingw/math/arm/s_rint.c +0 -86
  59. package/libc/mingw/math/arm/s_rintf.c +0 -51
  60. package/libc/mingw/math/bsd_private_base.h +0 -148
  61. package/libc/mingw/math/x86/acosf.c +0 -29
  62. package/libc/mingw/math/x86/atanf.c +0 -23
  63. package/libc/mingw/math/x86/atanl.c +0 -18
  64. package/libc/mingw/math/x86/ldexp.c +0 -23
  65. package/libc/mingw/math/x86/scalbn.S +0 -41
  66. package/libc/mingw/math/x86/scalbnf.S +0 -40
  67. package/libc/mingw/misc/btowc.c +0 -28
  68. package/libc/mingw/misc/wcstof.c +0 -66
  69. package/libc/mingw/misc/wcstoimax.c +0 -132
  70. package/libc/mingw/misc/wcstoumax.c +0 -126
  71. package/libc/mingw/misc/wctob.c +0 -29
  72. package/libc/mingw/misc/winbs_uint64.c +0 -6
  73. package/libc/mingw/misc/winbs_ulong.c +0 -6
  74. package/libc/mingw/misc/winbs_ushort.c +0 -6
  75. package/libc/mingw/stdio/_Exit.c +0 -10
  76. package/libc/mingw/stdio/_findfirst64i32.c +0 -21
  77. package/libc/mingw/stdio/_findnext64i32.c +0 -21
  78. package/libc/mingw/stdio/_fstat64i32.c +0 -37
  79. package/libc/mingw/stdio/_stat64i32.c +0 -37
  80. package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
  81. package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
  82. package/libc/mingw/stdio/_wstat64i32.c +0 -37
  83. package/libc/musl/src/legacy/valloc.c +0 -8
  84. package/libc/musl/src/math/exp_data.c +0 -182
  85. package/libc/musl/src/math/exp_data.h +0 -26
  86. package/libc/musl/src/math/pow_data.c +0 -180
  87. package/libc/musl/src/math/pow_data.h +0 -22
  88. package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
package/c/math.zig CHANGED
@@ -35,32 +35,32 @@ comptime {
35
35
  }
36
36
 
37
37
  if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
38
- symbol(&coshf, "coshf");
39
38
  symbol(&frexpf, "frexpf");
40
39
  symbol(&frexpl, "frexpl");
41
40
  symbol(&hypotf, "hypotf");
42
41
  symbol(&hypotl, "hypotl");
43
- symbol(&modff, "modff");
44
42
  symbol(&modfl, "modfl");
45
- symbol(&nan, "nan");
46
- symbol(&nanf, "nanf");
43
+ }
44
+
45
+ if ((builtin.target.isMinGW() and @sizeOf(f64) != @sizeOf(c_longdouble)) or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
46
+ symbol(&atanl, "atanl");
47
+ symbol(&copysignl, "copysignl");
47
48
  symbol(&nanl, "nanl");
48
- symbol(&tanhf, "tanhf");
49
49
  }
50
50
 
51
- if (builtin.target.isMinGW() or builtin.target.isMuslLibC()) {
52
- symbol(&rint, "rint");
53
- symbol(&rintf, "rintf");
51
+ if ((builtin.target.isMinGW() and builtin.cpu.arch == .x86) or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
52
+ symbol(&acosf, "acosf");
53
+ symbol(&atanf, "atanf");
54
+ symbol(&coshf, "coshf");
55
+ symbol(&modff, "modff");
56
+ symbol(&tanhf, "tanhf");
54
57
  }
55
58
 
56
59
  if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
57
60
  symbol(&acos, "acos");
58
- symbol(&acosf, "acosf");
59
61
  symbol(&acoshf, "acoshf");
60
62
  symbol(&asin, "asin");
61
63
  symbol(&atan, "atan");
62
- symbol(&atanf, "atanf");
63
- symbol(&atanl, "atanl");
64
64
  symbol(&cbrt, "cbrt");
65
65
  symbol(&cbrtf, "cbrtf");
66
66
  symbol(&cosh, "cosh");
@@ -74,6 +74,8 @@ comptime {
74
74
  symbol(&lrint, "lrint");
75
75
  symbol(&lrintf, "lrintf");
76
76
  symbol(&modf, "modf");
77
+ symbol(&nan, "nan");
78
+ symbol(&nanf, "nanf");
77
79
  symbol(&pow, "pow");
78
80
  symbol(&pow10, "pow10");
79
81
  symbol(&pow10f, "pow10f");
@@ -83,9 +85,9 @@ comptime {
83
85
  if (builtin.target.isMuslLibC()) {
84
86
  symbol(&copysign, "copysign");
85
87
  symbol(&copysignf, "copysignf");
88
+ symbol(&rint, "rint");
89
+ symbol(&rintf, "rintf");
86
90
  }
87
-
88
- symbol(&copysignl, "copysignl");
89
91
  }
90
92
 
91
93
  fn acos(x: f64) callconv(.c) f64 {
@@ -21,17 +21,17 @@ const RegisterManager = zig.RegisterManager(Renderer, Register, Ir.Ref, abi.allo
21
21
  const RegisterBitSet = RegisterManager.RegisterBitSet;
22
22
  const RegisterClass = struct {
23
23
  const gp: RegisterBitSet = blk: {
24
- var set = RegisterBitSet.initEmpty();
24
+ var set = RegisterBitSet.empty;
25
25
  for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
26
26
  break :blk set;
27
27
  };
28
28
  const x87: RegisterBitSet = blk: {
29
- var set = RegisterBitSet.initEmpty();
29
+ var set = RegisterBitSet.empty;
30
30
  for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
31
31
  break :blk set;
32
32
  };
33
33
  const sse: RegisterBitSet = blk: {
34
- var set = RegisterBitSet.initEmpty();
34
+ var set = RegisterBitSet.empty;
35
35
  for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
36
36
  break :blk set;
37
37
  };
@@ -424,6 +424,7 @@ pub fn main(init: process.Init.Minimal) !void {
424
424
  fatal("unable to parse jobs count '{s}': {t}", .{ text, err });
425
425
  if (n < 1) fatal("number of jobs must be at least 1", .{});
426
426
  threaded.setAsyncLimit(.limited(n));
427
+ graph.max_jobs = n;
427
428
  } else if (mem.eql(u8, arg, "--")) {
428
429
  builder.args = argsRest(args, arg_idx);
429
430
  break;
@@ -2746,7 +2746,7 @@ pub const Compiler = struct {
2746
2746
  // 1. Any permutation that does not have PRELOAD in it just uses the
2747
2747
  // default flags.
2748
2748
  const initial_flags = flags.*;
2749
- var flags_set = std.enums.EnumSet(rc.CommonResourceAttributes).initEmpty();
2749
+ var flags_set = std.enums.EnumSet(rc.CommonResourceAttributes).empty;
2750
2750
  for (tokens) |token| {
2751
2751
  const attribute = rc.CommonResourceAttributes.map.get(token.slice(source)).?;
2752
2752
  flags_set.insert(attribute);
@@ -2769,7 +2769,7 @@ pub const Compiler = struct {
2769
2769
  // 3. If none of DISCARDABLE, SHARED, or PURE is specified, then PRELOAD
2770
2770
  // implies `flags &= ~SHARED` and LOADONCALL implies `flags |= SHARED`
2771
2771
  const shared_set = comptime blk: {
2772
- var set = std.enums.EnumSet(rc.CommonResourceAttributes).initEmpty();
2772
+ var set = std.enums.EnumSet(rc.CommonResourceAttributes).empty;
2773
2773
  set.insert(.discardable);
2774
2774
  set.insert(.shared);
2775
2775
  set.insert(.pure);
@@ -6,6 +6,7 @@ const Io = std.Io;
6
6
  const fatal = std.process.fatal;
7
7
  const testing = std.testing;
8
8
  const assert = std.debug.assert;
9
+ const panic = std.debug.panic;
9
10
  const fuzz_abi = std.Build.abi.fuzz;
10
11
 
11
12
  pub const std_options: std.Options = .{
@@ -17,6 +18,8 @@ var fba: std.heap.FixedBufferAllocator = .init(&fba_buffer);
17
18
  var fba_buffer: [8192]u8 = undefined;
18
19
  var stdin_buffer: [4096]u8 = undefined;
19
20
  var stdout_buffer: [4096]u8 = undefined;
21
+ var stdin_reader: Io.File.Reader = undefined;
22
+ var stdout_writer: Io.File.Writer = undefined;
20
23
  const runner_threaded_io: Io = Io.Threaded.global_single_threaded.io();
21
24
 
22
25
  /// Keep in sync with logic in `std.Build.addRunArtifact` which decides whether
@@ -38,10 +41,10 @@ pub fn main(init: std.process.Init.Minimal) void {
38
41
  }
39
42
 
40
43
  if (need_simple) {
41
- return mainSimple() catch |err| std.debug.panic("test failure: {t}", .{err});
44
+ return mainSimple() catch |err| panic("test failure: {t}", .{err});
42
45
  }
43
46
 
44
- const args = init.args.toSlice(fba.allocator()) catch |err| std.debug.panic("unable to parse command line args: {t}", .{err});
47
+ const args = init.args.toSlice(fba.allocator()) catch |err| panic("unable to parse command line args: {t}", .{err});
45
48
 
46
49
  var listen = false;
47
50
  var opt_cache_dir: ?[]const u8 = null;
@@ -55,7 +58,7 @@ pub fn main(init: std.process.Init.Minimal) void {
55
58
  } else if (std.mem.startsWith(u8, arg, "--cache-dir")) {
56
59
  opt_cache_dir = arg["--cache-dir=".len..];
57
60
  } else {
58
- std.debug.panic("unrecognized command line argument: {s}", .{arg});
61
+ panic("unrecognized command line argument: {s}", .{arg});
59
62
  }
60
63
  }
61
64
 
@@ -65,7 +68,7 @@ pub fn main(init: std.process.Init.Minimal) void {
65
68
  }
66
69
 
67
70
  if (listen) {
68
- return mainServer(init) catch |err| std.debug.panic("internal test runner failure: {t}", .{err});
71
+ return mainServer(init) catch |err| panic("internal test runner failure: {t}", .{err});
69
72
  } else {
70
73
  return mainTerminal(init);
71
74
  }
@@ -73,24 +76,14 @@ pub fn main(init: std.process.Init.Minimal) void {
73
76
 
74
77
  fn mainServer(init: std.process.Init.Minimal) !void {
75
78
  @disableInstrumentation();
76
- var stdin_reader = Io.File.stdin().readerStreaming(runner_threaded_io, &stdin_buffer);
77
- var stdout_writer = Io.File.stdout().writerStreaming(runner_threaded_io, &stdout_buffer);
79
+ stdin_reader = .initStreaming(.stdin(), runner_threaded_io, &stdin_buffer);
80
+ stdout_writer = .initStreaming(.stdout(), runner_threaded_io, &stdout_buffer);
78
81
  var server = try std.zig.Server.init(.{
79
82
  .in = &stdin_reader.interface,
80
83
  .out = &stdout_writer.interface,
81
84
  .zig_version = builtin.zig_version_string,
82
85
  });
83
86
 
84
- if (builtin.fuzz) {
85
- const coverage = fuzz_abi.fuzzer_coverage();
86
- try server.serveCoverageIdMessage(
87
- coverage.id,
88
- coverage.runs,
89
- coverage.unique,
90
- coverage.seen,
91
- );
92
- }
93
-
94
87
  while (true) {
95
88
  const hdr = try server.receiveMessage();
96
89
  switch (hdr.tag) {
@@ -180,48 +173,75 @@ fn mainServer(init: std.process.Init.Minimal) !void {
180
173
  // since they are not present.
181
174
  if (!builtin.fuzz) unreachable;
182
175
 
183
- const index: u32 = @intCast(index: {
184
- testing.allocator_instance = .{};
185
- defer if (testing.allocator_instance.deinit() == .leak) {
186
- @panic("internal test runner memory leak");
187
- };
188
-
189
- const name_len = try server.receiveBody_u32();
190
- const name = try server.in.readAlloc(testing.allocator, @intCast(name_len));
191
- defer testing.allocator.free(name);
192
- for (0.., builtin.test_functions) |i, test_fn| {
193
- if (std.mem.eql(u8, name, test_fn.name)) {
194
- break :index i;
195
- }
196
- } else {
197
- std.debug.panic("fuzz test {s} no longer exists", .{name});
198
- }
176
+ var gpa_instance: std.heap.DebugAllocator(.{}) = .init;
177
+ defer if (gpa_instance.deinit() == .leak) {
178
+ @panic("internal test runner memory leak");
179
+ };
180
+ const gpa = gpa_instance.allocator();
181
+ var io_instance: Io.Threaded = .init(gpa, .{
182
+ .argv0 = .init(init.args),
183
+ .environ = init.environ,
199
184
  });
185
+ defer io_instance.deinit();
186
+ const io = io_instance.io();
187
+
200
188
  const mode: fuzz_abi.LimitKind = @enumFromInt(try server.receiveBody_u8());
201
189
  const amount_or_instance = try server.receiveBody_u64();
190
+ const main_instance = mode == .iterations or amount_or_instance == 0;
191
+
192
+ if (main_instance) {
193
+ const coverage = fuzz_abi.fuzzer_coverage();
194
+ try server.serveCoverageIdMessage(
195
+ coverage.id,
196
+ coverage.runs,
197
+ coverage.unique,
198
+ coverage.seen,
199
+ );
200
+ }
202
201
 
203
- const test_fn = builtin.test_functions[index];
204
- const entry_addr = @intFromPtr(test_fn.func);
202
+ const n_tests: u32 = try server.receiveBody_u32();
203
+ const test_indexes = try gpa.alloc(u32, n_tests);
204
+ defer gpa.free(test_indexes);
205
+ fuzz_runner = .{
206
+ .indexes = test_indexes,
207
+ .server = &server,
208
+ .gpa = gpa,
209
+ .io = io,
210
+ .input_poller = undefined,
211
+ };
205
212
 
206
- try server.serveU64Message(.fuzz_start_addr, fuzz_abi.fuzzer_unslide_address(entry_addr));
207
- defer if (testing.allocator_instance.deinit() == .leak) std.process.exit(1);
208
- is_fuzz_test = false;
209
- fuzz_test_index = index;
210
- fuzz_mode = mode;
211
- fuzz_amount_or_instance = amount_or_instance;
213
+ {
214
+ var large_name_buf: std.ArrayList(u8) = .empty;
215
+ defer large_name_buf.deinit(gpa);
216
+ for (test_indexes) |*i| {
217
+ const name_len = try server.receiveBody_u32();
218
+ const name = if (name_len <= server.in.buffer.len)
219
+ try server.in.take(name_len)
220
+ else large_name: {
221
+ try large_name_buf.resize(gpa, name_len);
222
+ try server.in.readSliceAll(large_name_buf.items);
223
+ break :large_name large_name_buf.items;
224
+ };
225
+
226
+ for (0.., builtin.test_functions) |test_i, test_fn| {
227
+ if (std.mem.eql(u8, name, test_fn.name)) {
228
+ i.* = @intCast(test_i);
229
+ break;
230
+ }
231
+ } else {
232
+ panic("fuzz test {s} no longer exists", .{name});
233
+ }
212
234
 
213
- test_fn.func() catch |err| switch (err) {
214
- error.SkipZigTest => return,
215
- else => {
216
- if (@errorReturnTrace()) |trace| {
217
- std.debug.dumpStackTrace(trace);
235
+ if (main_instance) {
236
+ const relocated_entry_addr = @intFromPtr(builtin.test_functions[i.*].func);
237
+ const entry_addr = fuzz_abi.fuzzer_unslide_address(relocated_entry_addr);
238
+ try server.serveU64Message(.fuzz_start_addr, entry_addr);
218
239
  }
219
- std.debug.print("failed with error.{t}\n", .{err});
220
- std.process.exit(1);
221
- },
222
- };
223
- if (!is_fuzz_test) @panic("missed call to std.testing.fuzz");
224
- if (log_err_count != 0) @panic("error logs detected");
240
+ }
241
+ }
242
+
243
+ fuzz_abi.fuzzer_main(n_tests, testing.random_seed, mode, amount_or_instance);
244
+
225
245
  assert(mode != .forever);
226
246
  std.process.exit(0);
227
247
  },
@@ -382,16 +402,126 @@ pub fn mainSimple() anyerror!void {
382
402
  passed += 1;
383
403
  }
384
404
  if (enable_print) {
385
- var stdout_writer = stdout.writer(runner_threaded_io, &.{});
386
- stdout_writer.interface.print("{} passed, {} skipped, {} failed\n", .{ passed, skipped, failed }) catch {};
405
+ var unbuffered_stdout_writer = stdout.writer(runner_threaded_io, &.{});
406
+ unbuffered_stdout_writer.interface.print(
407
+ "{} passed, {} skipped, {} failed\n",
408
+ .{ passed, skipped, failed },
409
+ ) catch {};
387
410
  }
388
411
  if (failed != 0) std.process.exit(1);
389
412
  }
390
413
 
391
414
  var is_fuzz_test: bool = undefined;
392
- var fuzz_test_index: u32 = undefined;
393
- var fuzz_mode: fuzz_abi.LimitKind = undefined;
394
- var fuzz_amount_or_instance: u64 = undefined;
415
+ var fuzz_runner: if (builtin.fuzz) struct {
416
+ indexes: []u32,
417
+ server: *std.zig.Server,
418
+ gpa: std.mem.Allocator,
419
+ io: Io,
420
+ input_poller: Io.Future(Io.Cancelable!void),
421
+
422
+ comptime {
423
+ assert(builtin.fuzz); // `fuzz_runner` was analyzed in non-fuzzing compilation
424
+ }
425
+
426
+ export fn runner_test_run(i: u32) void {
427
+ @disableInstrumentation();
428
+
429
+ fuzz_runner.server.serveU32Message(.fuzz_test_change, i) catch |e| switch (e) {
430
+ error.WriteFailed => panic("failed to write to stdout: {t}", .{stdout_writer.err.?}),
431
+ };
432
+
433
+ testing.allocator_instance = .{};
434
+ defer if (testing.allocator_instance.deinit() == .leak) std.process.exit(1);
435
+ is_fuzz_test = false;
436
+
437
+ builtin.test_functions[fuzz_runner.indexes[i]].func() catch |err| switch (err) {
438
+ error.SkipZigTest => return,
439
+ else => {
440
+ if (@errorReturnTrace()) |trace| {
441
+ std.debug.dumpStackTrace(trace);
442
+ }
443
+ std.debug.print("failed with error.{t}\n", .{err});
444
+ std.process.exit(1);
445
+ },
446
+ };
447
+
448
+ if (!is_fuzz_test) @panic("missed call to std.testing.fuzz");
449
+ if (log_err_count != 0) @panic("error logs detected");
450
+ }
451
+
452
+ export fn runner_test_name(i: u32) fuzz_abi.Slice {
453
+ @disableInstrumentation();
454
+ return .fromSlice(builtin.test_functions[fuzz_runner.indexes[i]].name);
455
+ }
456
+
457
+ export fn runner_broadcast_input(test_i: u32, bytes_slice: fuzz_abi.Slice) void {
458
+ @disableInstrumentation();
459
+ const bytes = bytes_slice.toSlice();
460
+ fuzz_runner.server.serveBroadcastFuzzInputMessage(test_i, bytes) catch |e| switch (e) {
461
+ error.WriteFailed => panic("failed to write to stdout: {t}", .{stdout_writer.err.?}),
462
+ };
463
+ }
464
+
465
+ export fn runner_start_input_poller() void {
466
+ @disableInstrumentation();
467
+ const future = fuzz_runner.io.concurrent(inputPoller, .{}) catch |e| switch (e) {
468
+ error.ConcurrencyUnavailable => @panic("failed to spawn concurrent fuzz input poller"),
469
+ };
470
+ fuzz_runner.input_poller = future;
471
+ }
472
+
473
+ export fn runner_stop_input_poller() void {
474
+ @disableInstrumentation();
475
+ assert(fuzz_runner.input_poller.cancel(fuzz_runner.io) == error.Canceled);
476
+ }
477
+
478
+ export fn runner_futex_wait(ptr: *const u32, expected: u32) bool {
479
+ @disableInstrumentation();
480
+ return fuzz_runner.io.futexWait(u32, ptr, expected) == error.Canceled;
481
+ }
482
+
483
+ export fn runner_futex_wake(ptr: *const u32, waiters: u32) void {
484
+ @disableInstrumentation();
485
+ fuzz_runner.io.futexWake(u32, ptr, waiters);
486
+ }
487
+
488
+ fn inputPoller() Io.Cancelable!void {
489
+ @disableInstrumentation();
490
+ switch (inputPollerInner()) {
491
+ error.Canceled => return error.Canceled,
492
+ error.ReadFailed => {
493
+ if (stdin_reader.err.? == error.Canceled) return error.Canceled;
494
+ panic("failed to read from stdin: {t}", .{stdin_reader.err.?});
495
+ },
496
+ error.EndOfStream => @panic("unexpected end of stdin"),
497
+ }
498
+ }
499
+
500
+ fn inputPollerInner() (Io.Cancelable || Io.Reader.Error) {
501
+ @disableInstrumentation();
502
+ const server = fuzz_runner.server;
503
+ var large_bytes_list: std.ArrayList(u8) = .empty;
504
+ defer large_bytes_list.deinit(fuzz_runner.gpa);
505
+ while (true) {
506
+ const hdr = try server.receiveMessage();
507
+ if (hdr.tag != .new_fuzz_input) {
508
+ panic("unexpected message: {x}\n", .{@intFromEnum(hdr.tag)});
509
+ }
510
+ const test_i = try server.receiveBody_u32();
511
+ const input_len = hdr.bytes_len - 4;
512
+ const bytes = if (input_len <= server.in.buffer.len)
513
+ try server.in.take(input_len)
514
+ else bytes: {
515
+ large_bytes_list.resize(fuzz_runner.gpa, @intCast(input_len)) catch @panic("OOM");
516
+ try server.in.readSliceAll(large_bytes_list.items);
517
+ break :bytes large_bytes_list.items;
518
+ };
519
+ if (fuzz_abi.fuzzer_receive_input(test_i, .fromSlice(bytes))) {
520
+ return error.Canceled;
521
+ }
522
+ }
523
+ }
524
+ } else void = undefined;
395
525
 
396
526
  pub fn fuzz(
397
527
  context: anytype,
@@ -448,16 +578,18 @@ pub fn fuzz(
448
578
  return false;
449
579
  }
450
580
  };
581
+
451
582
  if (builtin.fuzz) {
583
+ // Preserve the calling test's allocator state
452
584
  const prev_allocator_state = testing.allocator_instance;
453
585
  testing.allocator_instance = .{};
454
586
  defer testing.allocator_instance = prev_allocator_state;
455
- global.ctx = context;
456
587
 
457
- fuzz_abi.fuzzer_set_test(&global.test_one, .fromSlice(builtin.test_functions[fuzz_test_index].name));
588
+ global.ctx = context;
589
+ fuzz_abi.fuzzer_set_test(&global.test_one);
458
590
  for (options.corpus) |elem|
459
591
  fuzz_abi.fuzzer_new_input(.fromSlice(elem));
460
- fuzz_abi.fuzzer_main(fuzz_mode, fuzz_amount_or_instance);
592
+ fuzz_abi.fuzzer_start_test();
461
593
  return;
462
594
  }
463
595