summaryrefslogtreecommitdiff
path: root/introspect/src/freestanding_check.zig
blob: ad88d0e14605113ad94197babb05922a47f056e9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! A tiny freestanding root proving that `core` and `vars` compile without an
//! OS: `zig build introspect-check-freestanding` builds this for riscv32-freestanding-none.
//! It instantiates `Server(cfg)` with static Storage/Shared, exposes one
//! variable, and runs one push/step over a canned Tversion frame. It must not
//! import scratch.zig (allocator) or anything OS-specific.
const std = @import("std");
const core = @import("core.zig");
const Writer = std.Io.Writer;

const Build = struct {
    pub const zig_version: []const u8 = @import("builtin").zig_version_string;
    pub const target: []const u8 = "riscv32-freestanding-none";
    pub const optimize: []const u8 = "check";
    pub const time: []const u8 = "1970-01-01T00:00:00Z";
    pub const change: []const u8 = "none";
};

const State = struct { ticks: u32, phase: enum { idle, busy }, inner: struct { x: f32 } };

const Fns = struct {
    pub fn ticks(ctx: *anyopaque, w: *Writer) anyerror!void {
        const s: *State = @ptrCast(@alignCast(ctx));
        try w.print("{d}", .{s.ticks});
    }
};

fn ctl(ctx: *anyopaque, cmd: []const u8, out: *Writer) anyerror!void {
    const s: *State = @ptrCast(@alignCast(ctx));
    if (std.mem.startsWith(u8, cmd, "reset")) s.ticks = 0;
    try out.writeAll("ok");
}

const cfg: core.Config = .{
    .name = "fw",
    .build = Build,
    .types = &.{ State, core.NodeStat },
    .decls_of = Fns,
    .fns = Fns,
    .ctl = &ctl,
    .msize = 2048,
    .max_fids = 16,
    .snapshot_slots = 2,
    .snapshot_bytes = 1024,
};

const S = core.Server(cfg);

var state: State = .{ .ticks = 0, .phase = .idle, .inner = .{ .x = 0 } };
var storage: S.Storage = undefined;
var shared: S.Shared = undefined;
var conn: S.Conn = undefined;

/// Tversion msize=2048 version="9P2000".
const tversion = [_]u8{ 19, 0, 0, 0, 100, 0xFF, 0xFF, 0, 8, 0, 0, 6, 0, '9', 'P', '2', '0', '0', '0' };

/// Runs one Tversion through the engine; returns the number of reply bytes.
pub export fn introspect_check() u32 {
    shared = .init(&state);
    shared.expose("state", &state) catch unreachable;
    conn = .init(&shared, &storage, cfg.msize);
    _ = conn.push(&tversion);
    _ = conn.step() catch return 0;
    const out = conn.output();
    conn.wrote(out.len);
    return @intCast(out.len);
}

pub export fn _start() noreturn {
    _ = introspect_check();
    while (true) {}
}