lib/stabilizer/src/stack.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 const config = @import("config.zig");
 4 const Marsaglia = @import("rng.zig").Marsaglia;
 5 
 6 const Allocator = std.mem.Allocator;
 7 const StackConfig = config.StackConfig;
 8 
 9 pub const StackPad = struct {
10     unit: u8,
11     bytes: usize,
12 };
13 
14 pub const StackPads = struct {
15     allocator: Allocator,
16     config: StackConfig,
17     entries: []u8 = &.{},
18     index: usize = 0,
19 
20     pub fn init(allocator: Allocator, stack_config: StackConfig, rng: *Marsaglia) !StackPads {
21         var self: StackPads = .{
22             .allocator = allocator,
23             .config = normalizeStackConfig(stack_config),
24         };
25         if (self.config.enabled) {
26             self.entries = try allocator.alloc(u8, self.config.entries);
27             self.refill(rng);
28         }
29         return self;
30     }
31 
32     pub fn deinit(self: *StackPads) void {
33         if (self.entries.len > 0) self.allocator.free(self.entries);
34         self.* = undefined;
35     }
36 
37     pub fn refill(self: *StackPads, rng: *Marsaglia) void {
38         for (self.entries) |*entry| entry.* = rng.nextByte();
39         self.index = 0;
40     }
41 
42     pub fn next(self: *StackPads, rng: *Marsaglia) StackPad {
43         if (!self.config.enabled) return .{ .unit = 0, .bytes = 0 };
44         if (self.index >= self.entries.len) self.refill(rng);
45         const unit = self.entries[self.index];
46         self.index += 1;
47         return .{ .unit = unit, .bytes = @as(usize, unit) * self.config.alignment };
48     }
49 };
50 
51 fn normalizeStackConfig(stack_config: StackConfig) StackConfig {
52     var out = stack_config;
53     if (out.entries == 0) out.entries = 1;
54     out.alignment = config.stack_alignment;
55     return out;
56 }