lib/choir/src/backends/artifact/model/metadata.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 const std = @import("std");
  2 const Allocator = std.mem.Allocator;
  3 const artifact = @import("root.zig");
  4 const slice = artifact.slice;
  5 
  6 pub const Architecture = enum(u8) {
  7     unknown = 1,
  8     x86_64 = 2,
  9     aarch64 = 3,
 10     wasm = 4,
 11 };
 12 
 13 pub const Endianness = enum(u8) {
 14     little = 1,
 15     big = 2,
 16 };
 17 
 18 pub const ArtifactKind = enum(u8) {
 19     unknown = 1,
 20     machine_code = 2,
 21     object_file = 3,
 22     webassembly_module = 4,
 23     assembly = 5,
 24     source_text = 6,
 25     debug_info = 7,
 26     container = 8,
 27 };
 28 
 29 pub const Target = struct {
 30     architecture: Architecture = .unknown,
 31     triple: ?[]const u8 = null,
 32     vendor: ?[]const u8 = null,
 33     os: ?[]const u8 = null,
 34     environment: ?[]const u8 = null,
 35     cpu: ?[]const u8 = null,
 36     features: []const []const u8 = &.{},
 37 
 38     pub fn dupe(self: Target, allocator: Allocator) Allocator.Error!Target {
 39         var out = Target{ .architecture = self.architecture };
 40         errdefer out.deinit(allocator);
 41         out.triple = try slice.dupeOptional(allocator, self.triple);
 42         out.vendor = try slice.dupeOptional(allocator, self.vendor);
 43         out.os = try slice.dupeOptional(allocator, self.os);
 44         out.environment = try slice.dupeOptional(allocator, self.environment);
 45         out.cpu = try slice.dupeOptional(allocator, self.cpu);
 46         out.features = try slice.dupeList(allocator, self.features);
 47         return out;
 48     }
 49 
 50     pub fn deinit(self: *Target, allocator: Allocator) void {
 51         slice.freeOptional(allocator, self.triple);
 52         slice.freeOptional(allocator, self.vendor);
 53         slice.freeOptional(allocator, self.os);
 54         slice.freeOptional(allocator, self.environment);
 55         slice.freeOptional(allocator, self.cpu);
 56         slice.freeList(allocator, self.features);
 57         self.* = .{};
 58     }
 59 
 60     pub fn eql(self: Target, other: Target) bool {
 61         if (self.architecture != other.architecture or
 62             !slice.optionalEqual(self.triple, other.triple) or
 63             !slice.optionalEqual(self.vendor, other.vendor) or
 64             !slice.optionalEqual(self.os, other.os) or
 65             !slice.optionalEqual(self.environment, other.environment) or
 66             !slice.optionalEqual(self.cpu, other.cpu) or
 67             self.features.len != other.features.len)
 68         {
 69             return false;
 70         }
 71         for (self.features, other.features) |left, right| {
 72             if (!std.mem.eql(u8, left, right)) return false;
 73         }
 74         return true;
 75     }
 76 };
 77 
 78 pub const Abi = struct {
 79     name: ?[]const u8 = null,
 80     calling_convention: ?[]const u8 = null,
 81     object_format: ?[]const u8 = null,
 82     pointer_width_bits: ?u16 = null,
 83     endianness: ?Endianness = null,
 84 
 85     pub fn dupe(self: Abi, allocator: Allocator) Allocator.Error!Abi {
 86         var out = Abi{
 87             .pointer_width_bits = self.pointer_width_bits,
 88             .endianness = self.endianness,
 89         };
 90         errdefer out.deinit(allocator);
 91         out.name = try slice.dupeOptional(allocator, self.name);
 92         out.calling_convention = try slice.dupeOptional(allocator, self.calling_convention);
 93         out.object_format = try slice.dupeOptional(allocator, self.object_format);
 94         return out;
 95     }
 96 
 97     pub fn deinit(self: *Abi, allocator: Allocator) void {
 98         slice.freeOptional(allocator, self.name);
 99         slice.freeOptional(allocator, self.calling_convention);
100         slice.freeOptional(allocator, self.object_format);
101         self.* = .{};
102     }
103 
104     pub fn eql(self: Abi, other: Abi) bool {
105         return slice.optionalEqual(self.name, other.name) and
106             slice.optionalEqual(self.calling_convention, other.calling_convention) and
107             slice.optionalEqual(self.object_format, other.object_format) and
108             self.pointer_width_bits == other.pointer_width_bits and
109             self.endianness == other.endianness;
110     }
111 };
112 
113 pub const Metadata = struct {
114     kind: ArtifactKind = .unknown,
115     producer: ?[]const u8 = null,
116     target: Target = .{},
117     abi: Abi = .{},
118 
119     pub fn dupe(self: Metadata, allocator: Allocator) Allocator.Error!Metadata {
120         var out = Metadata{ .kind = self.kind };
121         errdefer out.deinit(allocator);
122         out.producer = try slice.dupeOptional(allocator, self.producer);
123         out.target = try self.target.dupe(allocator);
124         out.abi = try self.abi.dupe(allocator);
125         return out;
126     }
127 
128     pub fn deinit(self: *Metadata, allocator: Allocator) void {
129         slice.freeOptional(allocator, self.producer);
130         self.target.deinit(allocator);
131         self.abi.deinit(allocator);
132         self.* = .{};
133     }
134 
135     pub fn eql(self: Metadata, other: Metadata) bool {
136         return self.kind == other.kind and
137             slice.optionalEqual(self.producer, other.producer) and
138             self.target.eql(other.target) and
139             self.abi.eql(other.abi);
140     }
141 };