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 }