lib/machine/src/world/manifest/encode.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const fabric = @import("../../fabric/root.zig");
2 const os = @import("os");
3 const schema = @import("schema.zig");
4 const std = @import("std");
5 const world = @import("../root.zig");
6
7 const wire = os.abi.wire;
8
9 pub fn manifest(
10 value: *const world.Cut,
11 output: *[schema.stream_bytes]u8,
12 ) world.Error!void {
13 try world.verify(value.*);
14 var encoded: [schema.stream_bytes]u8 = @splat(0);
15 encodeEnvelope(&encoded);
16 encodeRoot(value.root, &encoded);
17 for (value.nodes[0..value.root.node_count], 0..) |node, index| {
18 encodeNode(node, index, &encoded);
19 }
20 output.* = encoded;
21 }
22
23 fn encodeEnvelope(output: *[schema.stream_bytes]u8) void {
24 const layout = schema.Envelope;
25 @memcpy(output[layout.magic_offset..layout.version_offset], &schema.magic);
26 put16(output, layout.version_offset, schema.version);
27 put16(output, layout.stream_bytes_offset, schema.stream_bytes);
28 put16(output, layout.flags_offset, schema.flags);
29 put16(output, layout.format_offset, schema.format);
30 put16(output, layout.world_dialect_offset, @backingInt(world.Dialect.connected_world_v1));
31 put16(
32 output,
33 layout.fabric_dialect_offset,
34 @backingInt(fabric.Dialect.ordered_effect_fabric_v3),
35 );
36 put16(output, layout.node_capacity_offset, world.node_limit);
37 put16(output, layout.node_bytes_offset, schema.node_bytes);
38 put16(output, layout.digest_bytes_offset, schema.digest_bytes);
39 put16(output, layout.root_bytes_offset, schema.root_bytes);
40 }
41
42 fn encodeRoot(value: world.Root, output: *[schema.stream_bytes]u8) void {
43 const layout = schema.RootLayout;
44 putDigest(output, layout.digest_offset, value.digest);
45 put16(output, layout.dialect_offset, @backingInt(value.dialect));
46 output[layout.node_count_offset] = value.node_count;
47 putDigest(output, layout.contract_offset, value.machine_contract.digest);
48 putDigest(output, layout.fabric_digest_offset, value.fabric.digest);
49 put16(output, layout.fabric_dialect_offset, @backingInt(value.fabric.dialect));
50 putDigest(
51 output,
52 layout.fabric_contract_offset,
53 value.fabric.machine_contract.digest,
54 );
55 put64(output, layout.entry_frontier_offset, value.fabric.entry_frontier);
56 put64(output, layout.admission_frontier_offset, value.fabric.admission_frontier);
57 put64(output, layout.fault_frontier_offset, value.fabric.fault_frontier);
58 }
59
60 fn encodeNode(
61 value: world.Node,
62 index: usize,
63 output: *[schema.stream_bytes]u8,
64 ) void {
65 std.debug.assert(index < world.node_limit);
66 const layout = schema.NodeLayout;
67 const start = schema.nodes_offset + index * schema.node_bytes;
68 std.debug.assert(start + schema.node_bytes <= schema.material_limit);
69 @memcpy(output[start + layout.id_offset ..][0..16], &value.id.bytes);
70 putDigest(output, start + layout.root_digest_offset, value.machine.digest);
71 putDigest(output, start + layout.profile_digest_offset, value.machine.profile.digest);
72 putDigest(output, start + layout.state_digest_offset, value.machine.state.digest);
73 }
74
75 fn putDigest(
76 output: *[schema.stream_bytes]u8,
77 offset: usize,
78 value: os.abi.Digest,
79 ) void {
80 std.debug.assert(offset + schema.digest_bytes <= output.len);
81 @memcpy(output[offset..][0..schema.digest_bytes], &value);
82 }
83
84 fn put16(output: *[schema.stream_bytes]u8, offset: usize, value: anytype) void {
85 std.debug.assert(offset + 2 <= output.len);
86 wire.write16(output[offset..][0..2], @intCast(value));
87 }
88
89 fn put64(output: *[schema.stream_bytes]u8, offset: usize, value: u64) void {
90 std.debug.assert(offset + 8 <= output.len);
91 wire.write64(output[offset..][0..8], value);
92 }