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 }