lib/choir/src/backends/wasm/emission/module/section/code.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const wasm = @import("../../../root.zig");
 3 const emission = @import("../../root.zig");
 4 const common = @import("../root.zig").common;
 5 
 6 pub fn prepareBodies(
 7     plan: *emission.Plan,
 8     module: *common.ir.Operation,
 9     frames: []emission.function.Frame,
10 ) emission.Error!void {
11     const module_op = try common.moduleOperation(module);
12     var ordinal: usize = 0;
13     var operations = module_op.getBodyBlock().getOperations();
14     while (operations.next()) |operation| : (ordinal += 1) {
15         const function = try common.functionOperation(operation);
16         if (function.isDeclaration()) continue;
17         var count = wasm.binary.Count{};
18         try emission.function.writeContent(
19             &count,
20             plan,
21             function,
22             ordinal,
23             plan.localCount(ordinal),
24             frames,
25         );
26         _ = try common.requireU32(count.len);
27         plan.functions[ordinal].body_bytes = count.len;
28     }
29 }
30 
31 pub fn write(
32     out: anytype,
33     plan: *const emission.Plan,
34     module: *common.ir.Operation,
35     frames: []emission.function.Frame,
36 ) emission.Error!void {
37     try common.writeSectionHeader(out, .code, plan.sections.code);
38     try writeBody(out, plan, module, frames);
39 }
40 
41 pub fn countBody(
42     plan: *const emission.Plan,
43     module: *common.ir.Operation,
44 ) emission.Error!usize {
45     var count = wasm.binary.Count{};
46     _ = try common.requireU32(plan.definitionCount());
47     try wasm.binary.writeUleb(&count, plan.definitionCount());
48     const module_op = try common.moduleOperation(module);
49     var ordinal: usize = 0;
50     var operations = module_op.getBodyBlock().getOperations();
51     while (operations.next()) |operation| : (ordinal += 1) {
52         const function = try common.functionOperation(operation);
53         if (function.isDeclaration()) continue;
54         const body_bytes = plan.bodyBytes(ordinal);
55         _ = try common.requireU32(body_bytes);
56         try wasm.binary.writeUleb(&count, body_bytes);
57         count.len = std.math.add(usize, count.len, body_bytes) catch
58             return error.CapacityOverflow;
59     }
60     return common.requireU32(count.len);
61 }
62 
63 fn writeBody(
64     out: anytype,
65     plan: *const emission.Plan,
66     module: *common.ir.Operation,
67     frames: []emission.function.Frame,
68 ) emission.Error!void {
69     _ = try common.requireU32(plan.definitionCount());
70     try wasm.binary.writeUleb(out, plan.definitionCount());
71     const module_op = try common.moduleOperation(module);
72     var ordinal: usize = 0;
73     var operations = module_op.getBodyBlock().getOperations();
74     while (operations.next()) |operation| : (ordinal += 1) {
75         const function = try common.functionOperation(operation);
76         if (function.isDeclaration()) continue;
77         const body_bytes = plan.bodyBytes(ordinal);
78         _ = try common.requireU32(body_bytes);
79         try wasm.binary.writeUleb(out, body_bytes);
80         try emission.function.writeContent(
81             out,
82             plan,
83             function,
84             ordinal,
85             plan.localCount(ordinal),
86             frames,
87         );
88     }
89 }