lib/choir/src/composition/module/verification/call.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const composition = @import("../../root.zig");
3 const model = @import("../root.zig");
4 const verification = @import("root.zig");
5
6 const abi = composition.abi;
7 const source = composition.source;
8
9 pub fn verifySpec(module: *const model.CompositionModule, spec: model.CallSiteSpec) verification.Error!void {
10 const resource_count = std.math.add(usize, spec.inputs.len, spec.outputs.len) catch return error.TooManyResources;
11 if (resource_count > abi.max_resources) return error.TooManyResources;
12 const caller = module.fragment(spec.caller) orelse return error.MissingFragment;
13 const callee = module.fragment(spec.callee) orelse return error.MissingFragment;
14 const semantic = module.source_module.callSite(spec.id) orelse return error.MissingSemanticCallSite;
15 if (caller.partition.value != semantic.caller.value or callee.partition.value != semantic.callee.value or
16 !std.mem.eql(u8, spec.name, semantic.name)) return error.SemanticCallSiteMismatch;
17 if (!std.mem.eql(u8, spec.provenance.path, semantic.provenance.path) or
18 !std.mem.eql(u8, spec.provenance.symbol, semantic.provenance.symbol) or
19 spec.provenance.line != semantic.provenance.line or spec.provenance.column != semantic.provenance.column)
20 {
21 return error.SemanticCallSiteMismatch;
22 }
23 if (!source.boundaryIdsEqual(spec.inputs, semantic.inputs) or !source.boundaryIdsEqual(spec.outputs, semantic.outputs)) {
24 return error.BoundaryContractMismatch;
25 }
26 const caller_export = caller.exportByName(spec.caller_export) orelse return error.MissingExport;
27 const runtime_import = caller.importByName(spec.runtime_import) orelse return error.MissingImport;
28 const callee_export = callee.exportByName(spec.callee_export) orelse return error.MissingExport;
29 if (runtime_import.kind != .runtime) return error.MissingImport;
30 if (!std.mem.eql(u8, runtime_import.symbol, abi.invoke_symbol)) return error.RuntimeSymbolMismatch;
31 if (spec.abi_version != abi.version or caller_export.abi_version != spec.abi_version or
32 runtime_import.abi_version != spec.abi_version or callee_export.abi_version != spec.abi_version)
33 {
34 return error.AbiMismatch;
35 }
36 }