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 }