This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig standard library. Private Function
fnnext(it: *StackIterator, io: Io) Result {
switch (it.*) {
.ctx_first => |context_ptr| {
// After the first frame, start actually unwinding.if (SelfInfo != voidandSelfInfo.can_unwindandfp_usability != .ideal) {
it.* = .{ .di = .init(context_ptr) };
} else {
constfp = applyOffset(context_ptr.getFp(), stack_bias) orelsereturn .end;
it.* = .{ .fp = fp };
}
// The caller expects *return* addresses, where they will subtract 1 to find the address of the call.// However, we have the actual current PC, which should not be adjusted. Compensate by adding 1.return .{ .frame = context_ptr.getPc() +| 1 };
},
.di => |*unwind_context| {
constdi = getSelfDebugInfo() catchunreachable;
constret_addr = di.unwindFrame(io, unwind_context) catch |err| {
constpc = unwind_context.pc;
constfp = applyOffset(unwind_context.getFp(), stack_bias) orelsereturn .end;
unwind_context.deinit();
it.* = .{ .fp = fp };
return .{ .switch_to_fp = .{
.address = pc,
.err = err,
} };
};
if (ret_addr <= 1) return .end;
return .{ .frame = ret_addr };
},
.fp => |fp| {
if (fp == 0) return .end; // we reached the "sentinel" base pointerconstbp_addr = applyOffset(fp, fp_to_bp_offset) orelsereturn .end;
constra_addr = applyOffset(fp, fp_to_ra_offset) orelsereturn .end;
if (bp_addr == 0or !mem.isAligned(bp_addr, @alignOf(usize)) orra_addr == 0or !mem.isAligned(ra_addr, @alignOf(usize)))
{
// This isn't valid, but it most likely indicates end of stack.return .end;
}
constbp_ptr: *constusize = @ptrFromInt(bp_addr);
constra_ptr: *constusize = @ptrFromInt(ra_addr);
constbp = applyOffset(bp_ptr.*, stack_bias) orelsereturn .end;
// If the stack grows downwards, `bp > fp` should always hold; conversely, if it// grows upwards, `bp < fp` should always hold. If that is not the case, this// frame is invalid, so we'll treat it as though we reached end of stack. The// exception is address 0, which is a graceful end-of-stack signal, in which case// *this* return address is valid and the *next* iteration will be the last.if (bp != 0andswitch (comptimebuiltin.target.stackGrowth()) {
.down => bp <= fp,
.up => bp >= fp,
}) return .end;
it.fp = bp;
constra = stripInstructionPtrAuthCode(ra_ptr.*);
if (ra <= 1) return .end;
return .{ .frame = ra };
},
}
}