| ... | ... | @@ -52,6 +52,17 @@ constant_items: std.MultiArrayList(Constant.Item), |
| 52 | 52 | constant_extra: std.ArrayListUnmanaged(u32), |
| 53 | 53 | constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb), |
| 54 | 54 | |
| 55 | metadata_map: std.AutoArrayHashMapUnmanaged(void, void), |
| 56 | metadata_items: std.MultiArrayList(Metadata.Item), |
| 57 | metadata_extra: std.ArrayListUnmanaged(u32), |
| 58 | metadata_strings: std.AutoArrayHashMapUnmanaged(String, void), |
| 59 | metadata_limbs: std.ArrayListUnmanaged(std.math.big.Limb), |
| 60 | metadata_forward_references: std.ArrayListUnmanaged(Metadata), |
| 61 | metadata_named: std.AutoArrayHashMapUnmanaged(String, struct { |
| 62 | len: u32, |
| 63 | index: Metadata.Item.ExtraIndex, |
| 64 | }), |
| 65 | |
| 55 | 66 | pub const expected_args_len = 16; |
| 56 | 67 | pub const expected_attrs_len = 16; |
| 57 | 68 | pub const expected_fields_len = 32; |
| ... | ... | @@ -6403,6 +6414,7 @@ pub const WipFunction = struct { |
| 6403 | 6414 | @intFromEnum(instruction) |
| 6404 | 6415 | ].toValue(), |
| 6405 | 6416 | .constant => |constant| constant.toValue(), |
| 6417 | .metadata => |metadata| metadata.toValue(), |
| 6406 | 6418 | }; |
| 6407 | 6419 | } |
| 6408 | 6420 | } = .{ .items = try gpa.alloc(Instruction.Index, self.instructions.len) }; |
| ... | ... | @@ -7400,10 +7412,10 @@ pub const Constant = enum(u32) { |
| 7400 | 7412 | false, |
| 7401 | 7413 | true, |
| 7402 | 7414 | none, |
| 7403 | | no_init = 1 << 31, |
| 7415 | no_init = (1 << 30) - 1, |
| 7404 | 7416 | _, |
| 7405 | 7417 | |
| 7406 | | const first_global: Constant = @enumFromInt(1 << 30); |
| 7418 | const first_global: Constant = @enumFromInt(1 << 29); |
| 7407 | 7419 | |
| 7408 | 7420 | pub const Tag = enum(u7) { |
| 7409 | 7421 | positive_integer, |
| ... | ... | @@ -8189,22 +8201,27 @@ pub const Value = enum(u32) { |
| 8189 | 8201 | true = first_constant + @intFromEnum(Constant.true), |
| 8190 | 8202 | _, |
| 8191 | 8203 | |
| 8192 | | const first_constant = 1 << 31; |
| 8204 | const first_constant = 1 << 30; |
| 8205 | const first_metadata = 1 << 31; |
| 8193 | 8206 | |
| 8194 | 8207 | pub fn unwrap(self: Value) union(enum) { |
| 8195 | 8208 | instruction: Function.Instruction.Index, |
| 8196 | 8209 | constant: Constant, |
| 8210 | metadata: Metadata, |
| 8197 | 8211 | } { |
| 8198 | 8212 | return if (@intFromEnum(self) < first_constant) |
| 8199 | 8213 | .{ .instruction = @enumFromInt(@intFromEnum(self)) } |
| 8214 | else if (@intFromEnum(self) < first_metadata) |
| 8215 | .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) } |
| 8200 | 8216 | else |
| 8201 | | .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) }; |
| 8217 | .{ .metadata = @enumFromInt(@intFromEnum(self) - first_metadata) }; |
| 8202 | 8218 | } |
| 8203 | 8219 | |
| 8204 | 8220 | pub fn typeOfWip(self: Value, wip: *const WipFunction) Type { |
| 8205 | 8221 | return switch (self.unwrap()) { |
| 8206 | 8222 | .instruction => |instruction| instruction.typeOfWip(wip), |
| 8207 | 8223 | .constant => |constant| constant.typeOf(wip.builder), |
| 8224 | .metadata => Type.metadata, |
| 8208 | 8225 | }; |
| 8209 | 8226 | } |
| 8210 | 8227 | |
| ... | ... | @@ -8212,12 +8229,13 @@ pub const Value = enum(u32) { |
| 8212 | 8229 | return switch (self.unwrap()) { |
| 8213 | 8230 | .instruction => |instruction| instruction.typeOf(function, builder), |
| 8214 | 8231 | .constant => |constant| constant.typeOf(builder), |
| 8232 | .metadata => Type.metadata, |
| 8215 | 8233 | }; |
| 8216 | 8234 | } |
| 8217 | 8235 | |
| 8218 | 8236 | pub fn toConst(self: Value) ?Constant { |
| 8219 | 8237 | return switch (self.unwrap()) { |
| 8220 | | .instruction => null, |
| 8238 | .instruction, .metadata => null, |
| 8221 | 8239 | .constant => |constant| constant, |
| 8222 | 8240 | }; |
| 8223 | 8241 | } |
| ... | ... | @@ -8243,6 +8261,7 @@ pub const Value = enum(u32) { |
| 8243 | 8261 | .constant = constant, |
| 8244 | 8262 | .builder = data.builder, |
| 8245 | 8263 | }, fmt_str, fmt_opts, writer), |
| 8264 | .metadata => unreachable, |
| 8246 | 8265 | } |
| 8247 | 8266 | } |
| 8248 | 8267 | pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(format) { |
| ... | ... | @@ -8253,11 +8272,239 @@ pub const Value = enum(u32) { |
| 8253 | 8272 | return switch (self.unwrap()) { |
| 8254 | 8273 | .instruction => |instruction| instruction.toLlvm(wip), |
| 8255 | 8274 | .constant => |constant| constant.toLlvm(wip.builder), |
| 8275 | .metadata => unreachable, |
| 8256 | 8276 | }; |
| 8257 | 8277 | } |
| 8258 | 8278 | }; |
| 8259 | 8279 | |
| 8260 | | pub const Metadata = enum(u32) { _ }; |
| 8280 | pub const MetadataString = enum(u32) { |
| 8281 | _, |
| 8282 | }; |
| 8283 | |
| 8284 | pub const Metadata = enum(u32) { |
| 8285 | none = 0, |
| 8286 | _, |
| 8287 | |
| 8288 | const first_forward_reference = 1 << 29; |
| 8289 | const first_local_metadata = 1 << 30; |
| 8290 | |
| 8291 | pub const Tag = enum(u6) { |
| 8292 | none, |
| 8293 | file, |
| 8294 | compile_unit, |
| 8295 | @"compile_unit optimized", |
| 8296 | subprogram, |
| 8297 | @"subprogram optimized", |
| 8298 | @"subprogram local", |
| 8299 | @"subprogram definition", |
| 8300 | @"subprogram optimized local", |
| 8301 | @"subprogram optimized definition", |
| 8302 | @"subprogram optimized local definition", |
| 8303 | @"subprogram local definition", |
| 8304 | lexical_block, |
| 8305 | location, |
| 8306 | basic_bool_type, |
| 8307 | basic_unsigned_type, |
| 8308 | basic_signed_type, |
| 8309 | basic_float_type, |
| 8310 | composite_struct_type, |
| 8311 | composite_union_type, |
| 8312 | composite_enumeration_type, |
| 8313 | composite_array_type, |
| 8314 | derived_pointer_type, |
| 8315 | derived_member_type, |
| 8316 | subroutine_type, |
| 8317 | enumerator_unsigned, |
| 8318 | enumerator_signed_positive, |
| 8319 | enumerator_signed_negative, |
| 8320 | subrange, |
| 8321 | tuple, |
| 8322 | module_flag, |
| 8323 | expression, |
| 8324 | local_var, |
| 8325 | parameter, |
| 8326 | global_var, |
| 8327 | @"global_var local", |
| 8328 | global_var_expression, |
| 8329 | constant, |
| 8330 | }; |
| 8331 | |
| 8332 | pub fn unwrap(self: Metadata, builder: *const Builder) Metadata { |
| 8333 | var metadata = self; |
| 8334 | var count: usize = 0; |
| 8335 | while (@intFromEnum(metadata) >= Metadata.first_forward_reference and |
| 8336 | @intFromEnum(metadata) < Metadata.first_local_metadata) |
| 8337 | { |
| 8338 | const index = @intFromEnum(metadata) - Metadata.first_forward_reference; |
| 8339 | metadata = builder.metadata_forward_references.items[index]; |
| 8340 | std.debug.assert(metadata != .none); |
| 8341 | count += 1; |
| 8342 | } |
| 8343 | return metadata; |
| 8344 | } |
| 8345 | |
| 8346 | pub const Item = struct { |
| 8347 | tag: Tag, |
| 8348 | data: ExtraIndex, |
| 8349 | |
| 8350 | const ExtraIndex = u32; |
| 8351 | }; |
| 8352 | |
| 8353 | pub const File = struct { |
| 8354 | path: MetadataString, |
| 8355 | name: MetadataString, |
| 8356 | }; |
| 8357 | |
| 8358 | pub const CompileUnit = struct { |
| 8359 | pub const Flags = struct { |
| 8360 | optimized: bool, |
| 8361 | }; |
| 8362 | |
| 8363 | file: Metadata, |
| 8364 | producer: MetadataString, |
| 8365 | enums: Metadata, |
| 8366 | globals: Metadata, |
| 8367 | }; |
| 8368 | |
| 8369 | pub const Subprogram = struct { |
| 8370 | pub const Flags = struct { |
| 8371 | optimized: bool, |
| 8372 | local: bool, |
| 8373 | definition: bool, |
| 8374 | debug_info_flags: u32, |
| 8375 | }; |
| 8376 | |
| 8377 | file: Metadata, |
| 8378 | name: MetadataString, |
| 8379 | linkage_name: MetadataString, |
| 8380 | line: u32, |
| 8381 | scope_line: u32, |
| 8382 | ty: Metadata, |
| 8383 | debug_info_flags: u32, |
| 8384 | compile_unit: Metadata, |
| 8385 | }; |
| 8386 | |
| 8387 | pub const LexicalBlock = struct { |
| 8388 | file: Metadata, |
| 8389 | scope: Metadata, |
| 8390 | line: u32, |
| 8391 | column: u32, |
| 8392 | }; |
| 8393 | |
| 8394 | pub const Location = struct { |
| 8395 | scope: Metadata, |
| 8396 | line: u32, |
| 8397 | column: u32, |
| 8398 | inlined_at: Metadata, |
| 8399 | }; |
| 8400 | |
| 8401 | pub const BasicType = struct { |
| 8402 | name: MetadataString, |
| 8403 | size_in_bits_lo: u32, |
| 8404 | size_in_bits_hi: u32, |
| 8405 | }; |
| 8406 | |
| 8407 | pub const CompositeType = struct { |
| 8408 | name: MetadataString, |
| 8409 | file: Metadata, |
| 8410 | scope: Metadata, |
| 8411 | line: u32, |
| 8412 | underlying_type: Metadata, |
| 8413 | size_in_bits_lo: u32, |
| 8414 | size_in_bits_hi: u32, |
| 8415 | align_in_bits_lo: u32, |
| 8416 | align_in_bits_hi: u32, |
| 8417 | fields_tuple: Metadata, |
| 8418 | }; |
| 8419 | |
| 8420 | pub const DerivedType = struct { |
| 8421 | name: MetadataString, |
| 8422 | file: Metadata, |
| 8423 | scope: Metadata, |
| 8424 | line: u32, |
| 8425 | underlying_type: Metadata, |
| 8426 | size_in_bits_lo: u32, |
| 8427 | size_in_bits_hi: u32, |
| 8428 | align_in_bits_lo: u32, |
| 8429 | align_in_bits_hi: u32, |
| 8430 | offset_in_bits_lo: u32, |
| 8431 | offset_in_bits_hi: u32, |
| 8432 | }; |
| 8433 | |
| 8434 | pub const SubroutineType = struct { |
| 8435 | types_tuple: Metadata, |
| 8436 | }; |
| 8437 | |
| 8438 | pub const Enumerator = struct { |
| 8439 | name: MetadataString, |
| 8440 | bit_width: u32, |
| 8441 | limbs_index: u32, |
| 8442 | limbs_len: u32, |
| 8443 | }; |
| 8444 | |
| 8445 | pub const Subrange = struct { |
| 8446 | lower_bound: Metadata, |
| 8447 | count: Metadata, |
| 8448 | }; |
| 8449 | |
| 8450 | pub const Expression = struct { |
| 8451 | elements_len: u32, |
| 8452 | |
| 8453 | // elements: [elements_len]u32 |
| 8454 | }; |
| 8455 | |
| 8456 | pub const Tuple = struct { |
| 8457 | elements_len: u32, |
| 8458 | |
| 8459 | // elements: [elements_len]Metadata |
| 8460 | }; |
| 8461 | |
| 8462 | pub const ModuleFlag = struct { |
| 8463 | behaviour: Metadata, |
| 8464 | name: MetadataString, |
| 8465 | constant: Metadata, |
| 8466 | }; |
| 8467 | |
| 8468 | pub const LocalVar = struct { |
| 8469 | name: MetadataString, |
| 8470 | file: Metadata, |
| 8471 | scope: Metadata, |
| 8472 | line: u32, |
| 8473 | ty: Metadata, |
| 8474 | }; |
| 8475 | |
| 8476 | pub const Parameter = struct { |
| 8477 | name: MetadataString, |
| 8478 | file: Metadata, |
| 8479 | scope: Metadata, |
| 8480 | line: u32, |
| 8481 | ty: Metadata, |
| 8482 | arg_no: u32, |
| 8483 | }; |
| 8484 | |
| 8485 | pub const GlobalVar = struct { |
| 8486 | pub const Flags = struct { |
| 8487 | local: bool, |
| 8488 | }; |
| 8489 | |
| 8490 | name: MetadataString, |
| 8491 | linkage_name: MetadataString, |
| 8492 | file: Metadata, |
| 8493 | scope: Metadata, |
| 8494 | line: u32, |
| 8495 | ty: Metadata, |
| 8496 | variable: Variable.Index, |
| 8497 | }; |
| 8498 | |
| 8499 | pub const GlobalVarExpression = struct { |
| 8500 | variable: Metadata, |
| 8501 | expression: Metadata, |
| 8502 | }; |
| 8503 | |
| 8504 | pub fn toValue(self: Metadata) Value { |
| 8505 | return @enumFromInt(Value.first_metadata + @intFromEnum(self)); |
| 8506 | } |
| 8507 | }; |
| 8261 | 8508 | |
| 8262 | 8509 | pub const InitError = error{ |
| 8263 | 8510 | InvalidLlvmTriple, |
| ... | ... | @@ -8306,6 +8553,14 @@ pub fn init(options: Options) InitError!Builder { |
| 8306 | 8553 | .constant_items = .{}, |
| 8307 | 8554 | .constant_extra = .{}, |
| 8308 | 8555 | .constant_limbs = .{}, |
| 8556 | |
| 8557 | .metadata_map = .{}, |
| 8558 | .metadata_items = .{}, |
| 8559 | .metadata_extra = .{}, |
| 8560 | .metadata_strings = .{}, |
| 8561 | .metadata_limbs = .{}, |
| 8562 | .metadata_forward_references = .{}, |
| 8563 | .metadata_named = .{}, |
| 8309 | 8564 | }; |
| 8310 | 8565 | if (self.useLibLlvm()) self.llvm = .{ |
| 8311 | 8566 | .context = llvm.Context.create(), |
| ... | ... | @@ -8395,6 +8650,7 @@ pub fn init(options: Options) InitError!Builder { |
| 8395 | 8650 | assert(try self.intConst(.i1, 0) == .false); |
| 8396 | 8651 | assert(try self.intConst(.i1, 1) == .true); |
| 8397 | 8652 | assert(try self.noneConst(.token) == .none); |
| 8653 | assert(try self.debugNone() == .none); |
| 8398 | 8654 | |
| 8399 | 8655 | return self; |
| 8400 | 8656 | } |
| ... | ... | @@ -8445,6 +8701,14 @@ pub fn deinit(self: *Builder) void { |
| 8445 | 8701 | self.constant_extra.deinit(self.gpa); |
| 8446 | 8702 | self.constant_limbs.deinit(self.gpa); |
| 8447 | 8703 | |
| 8704 | self.metadata_map.deinit(self.gpa); |
| 8705 | self.metadata_items.deinit(self.gpa); |
| 8706 | self.metadata_extra.deinit(self.gpa); |
| 8707 | self.metadata_strings.deinit(self.gpa); |
| 8708 | self.metadata_limbs.deinit(self.gpa); |
| 8709 | self.metadata_forward_references.deinit(self.gpa); |
| 8710 | self.metadata_named.deinit(self.gpa); |
| 8711 | |
| 8448 | 8712 | self.* = undefined; |
| 8449 | 8713 | } |
| 8450 | 8714 | |
| ... | ... | @@ -12042,6 +12306,1188 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite |
| 12042 | 12306 | return self.constantExtraDataTrail(T, index).data; |
| 12043 | 12307 | } |
| 12044 | 12308 | |
| 12309 | fn ensureUnusedMetadataCapacity( |
| 12310 | self: *Builder, |
| 12311 | count: usize, |
| 12312 | comptime Extra: type, |
| 12313 | trail_len: usize, |
| 12314 | ) Allocator.Error!void { |
| 12315 | try self.metadata_map.ensureUnusedCapacity(self.gpa, count); |
| 12316 | try self.metadata_items.ensureUnusedCapacity(self.gpa, count); |
| 12317 | try self.metadata_extra.ensureUnusedCapacity( |
| 12318 | self.gpa, |
| 12319 | count * (@typeInfo(Extra).Struct.fields.len + trail_len), |
| 12320 | ); |
| 12321 | } |
| 12322 | |
| 12323 | fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item.ExtraIndex { |
| 12324 | const result: Metadata.Item.ExtraIndex = @intCast(self.metadata_extra.items.len); |
| 12325 | inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| { |
| 12326 | const value = @field(extra, field.name); |
| 12327 | self.metadata_extra.appendAssumeCapacity(switch (field.type) { |
| 12328 | u32 => value, |
| 12329 | MetadataString, Metadata, Variable.Index, Value => @intFromEnum(value), |
| 12330 | else => @compileError("bad field type: " ++ @typeName(field.type)), |
| 12331 | }); |
| 12332 | } |
| 12333 | return result; |
| 12334 | } |
| 12335 | |
| 12336 | const MetadataExtraDataTrail = struct { |
| 12337 | index: Metadata.Item.ExtraIndex, |
| 12338 | |
| 12339 | fn nextMut(self: *MetadataExtraDataTrail, len: u32, comptime Item: type, builder: *Builder) []Item { |
| 12340 | const items: []Item = @ptrCast(builder.metadata_extra.items[self.index..][0..len]); |
| 12341 | self.index += @intCast(len); |
| 12342 | return items; |
| 12343 | } |
| 12344 | |
| 12345 | fn next( |
| 12346 | self: *MetadataExtraDataTrail, |
| 12347 | len: u32, |
| 12348 | comptime Item: type, |
| 12349 | builder: *const Builder, |
| 12350 | ) []const Item { |
| 12351 | const items: []const Item = @ptrCast(builder.metadata_extra.items[self.index..][0..len]); |
| 12352 | self.index += @intCast(len); |
| 12353 | return items; |
| 12354 | } |
| 12355 | }; |
| 12356 | |
| 12357 | fn metadataExtraDataTrail( |
| 12358 | self: *const Builder, |
| 12359 | comptime T: type, |
| 12360 | index: Metadata.Item.ExtraIndex, |
| 12361 | ) struct { data: T, trail: MetadataExtraDataTrail } { |
| 12362 | var result: T = undefined; |
| 12363 | const fields = @typeInfo(T).Struct.fields; |
| 12364 | inline for (fields, self.metadata_extra.items[index..][0..fields.len]) |field, value| |
| 12365 | @field(result, field.name) = switch (field.type) { |
| 12366 | u32 => value, |
| 12367 | MetadataString, Metadata, Variable.Index, Value => @enumFromInt(value), |
| 12368 | else => @compileError("bad field type: " ++ @typeName(field.type)), |
| 12369 | }; |
| 12370 | return .{ |
| 12371 | .data = result, |
| 12372 | .trail = .{ .index = index + @as(Metadata.Item.ExtraIndex, @intCast(fields.len)) }, |
| 12373 | }; |
| 12374 | } |
| 12375 | |
| 12376 | fn metadataExtraData(self: *const Builder, comptime T: type, index: Metadata.Item.ExtraIndex) T { |
| 12377 | return self.metadataExtraDataTrail(T, index).data; |
| 12378 | } |
| 12379 | |
| 12380 | fn metadataString(self: *Builder, str: String) Allocator.Error!MetadataString { |
| 12381 | const gop = try self.metadata_strings.getOrPut(self.gpa, str); |
| 12382 | if (!gop.found_existing) gop.key_ptr.* = str; |
| 12383 | |
| 12384 | return @enumFromInt(gop.index); |
| 12385 | } |
| 12386 | |
| 12387 | pub fn debugNamed(self: *Builder, name: String, operands: []const Metadata) Allocator.Error!void { |
| 12388 | try self.metadata_extra.ensureUnusedCapacity( |
| 12389 | self.gpa, |
| 12390 | operands.len * @sizeOf(Metadata), |
| 12391 | ); |
| 12392 | try self.metadata_named.ensureUnusedCapacity(self.gpa, 1); |
| 12393 | self.debugNamedAssumeCapacity(name, operands); |
| 12394 | } |
| 12395 | |
| 12396 | fn debugNone(self: *Builder) Allocator.Error!Metadata { |
| 12397 | try self.ensureUnusedMetadataCapacity(1, NoExtra, 0); |
| 12398 | return self.debugNoneAssumeCapacity(); |
| 12399 | } |
| 12400 | |
| 12401 | pub fn debugFile(self: *Builder, path: String, name: String) Allocator.Error!Metadata { |
| 12402 | try self.ensureUnusedMetadataCapacity(1, Metadata.File, 0); |
| 12403 | const metadata_path = try self.metadataString(path); |
| 12404 | const metadata_name = try self.metadataString(name); |
| 12405 | return self.debugFileAssumeCapacity(metadata_path, metadata_name); |
| 12406 | } |
| 12407 | |
| 12408 | pub fn debugCompileUnit( |
| 12409 | self: *Builder, |
| 12410 | file: Metadata, |
| 12411 | producer: String, |
| 12412 | enums: Metadata, |
| 12413 | globals: Metadata, |
| 12414 | flags: Metadata.CompileUnit.Flags, |
| 12415 | ) Allocator.Error!Metadata { |
| 12416 | try self.ensureUnusedMetadataCapacity(1, Metadata.CompileUnit, 0); |
| 12417 | const metadata_producer = try self.metadataString(producer); |
| 12418 | return self.debugCompileUnitAssumeCapacity(file, metadata_producer, enums, globals, flags); |
| 12419 | } |
| 12420 | |
| 12421 | pub fn debugSubprogram( |
| 12422 | self: *Builder, |
| 12423 | file: Metadata, |
| 12424 | name: String, |
| 12425 | linkage_name: String, |
| 12426 | line: u32, |
| 12427 | scope_line: u32, |
| 12428 | ty: Metadata, |
| 12429 | flags: Metadata.Subprogram.Flags, |
| 12430 | compile_unit: Metadata, |
| 12431 | ) Allocator.Error!Metadata { |
| 12432 | try self.ensureUnusedMetadataCapacity(1, Metadata.Subprogram, 0); |
| 12433 | const metadata_name = try self.metadataString(name); |
| 12434 | const metadata_linkage_name = try self.metadataString(linkage_name); |
| 12435 | return self.debugSubprogramAssumeCapacity( |
| 12436 | file, |
| 12437 | metadata_name, |
| 12438 | metadata_linkage_name, |
| 12439 | line, |
| 12440 | scope_line, |
| 12441 | ty, |
| 12442 | flags, |
| 12443 | compile_unit, |
| 12444 | ); |
| 12445 | } |
| 12446 | |
| 12447 | pub fn debugLexicalBlock(self: *Builder, file: Metadata, scope: Metadata, line: u32, column: u32) Allocator.Error!Metadata { |
| 12448 | try self.ensureUnusedMetadataCapacity(1, Metadata.LexicalBlock, 0); |
| 12449 | return self.debugLexicalBlockAssumeCapacity(file, scope, line, column); |
| 12450 | } |
| 12451 | |
| 12452 | pub fn debugLocation(self: *Builder, scope: Metadata, line: u32, column: u32, inlined_at: Metadata) Allocator.Error!Metadata { |
| 12453 | try self.ensureUnusedMetadataCapacity(1, Metadata.Location, 0); |
| 12454 | return self.debugLocationAssumeCapacity(scope, line, column, inlined_at); |
| 12455 | } |
| 12456 | |
| 12457 | pub fn debugBoolType(self: *Builder, name: String, size_in_bits: u64) Allocator.Error!Metadata { |
| 12458 | try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); |
| 12459 | const metadata_name = try self.metadataString(name); |
| 12460 | return self.debugBoolTypeAssumeCapacity(metadata_name, size_in_bits); |
| 12461 | } |
| 12462 | |
| 12463 | pub fn debugUnsignedType(self: *Builder, name: String, size_in_bits: u64) Allocator.Error!Metadata { |
| 12464 | try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); |
| 12465 | const metadata_name = try self.metadataString(name); |
| 12466 | return self.debugUnsignedTypeAssumeCapacity(metadata_name, size_in_bits); |
| 12467 | } |
| 12468 | |
| 12469 | pub fn debugSignedType(self: *Builder, name: String, size_in_bits: u64) Allocator.Error!Metadata { |
| 12470 | try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); |
| 12471 | const metadata_name = try self.metadataString(name); |
| 12472 | return self.debugSignedTypeAssumeCapacity(metadata_name, size_in_bits); |
| 12473 | } |
| 12474 | |
| 12475 | pub fn debugFloatType(self: *Builder, name: String, size_in_bits: u64) Allocator.Error!Metadata { |
| 12476 | try self.ensureUnusedMetadataCapacity(1, Metadata.BasicType, 0); |
| 12477 | const metadata_name = try self.metadataString(name); |
| 12478 | return self.debugFloatTypeAssumeCapacity(metadata_name, size_in_bits); |
| 12479 | } |
| 12480 | |
| 12481 | pub fn debugForwardReference(self: *Builder) Allocator.Error!Metadata { |
| 12482 | try self.metadata_forward_references.ensureUnusedCapacity(self.gpa, 1); |
| 12483 | return self.debugForwardReferenceAssumeCapacity(); |
| 12484 | } |
| 12485 | |
| 12486 | pub fn debugStructType( |
| 12487 | self: *Builder, |
| 12488 | name: String, |
| 12489 | file: Metadata, |
| 12490 | scope: Metadata, |
| 12491 | line: u32, |
| 12492 | underlying_type: Metadata, |
| 12493 | size_in_bits: u64, |
| 12494 | align_in_bits: u64, |
| 12495 | fields_tuple: Metadata, |
| 12496 | ) Allocator.Error!Metadata { |
| 12497 | try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); |
| 12498 | const metadata_name = try self.metadataString(name); |
| 12499 | return self.debugStructTypeAssumeCapacity( |
| 12500 | metadata_name, |
| 12501 | file, |
| 12502 | scope, |
| 12503 | line, |
| 12504 | underlying_type, |
| 12505 | size_in_bits, |
| 12506 | align_in_bits, |
| 12507 | fields_tuple, |
| 12508 | ); |
| 12509 | } |
| 12510 | |
| 12511 | pub fn debugUnionType( |
| 12512 | self: *Builder, |
| 12513 | name: String, |
| 12514 | file: Metadata, |
| 12515 | scope: Metadata, |
| 12516 | line: u32, |
| 12517 | underlying_type: Metadata, |
| 12518 | size_in_bits: u64, |
| 12519 | align_in_bits: u64, |
| 12520 | fields_tuple: Metadata, |
| 12521 | ) Allocator.Error!Metadata { |
| 12522 | try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); |
| 12523 | const metadata_name = try self.metadataString(name); |
| 12524 | return self.debugUnionTypeAssumeCapacity( |
| 12525 | metadata_name, |
| 12526 | file, |
| 12527 | scope, |
| 12528 | line, |
| 12529 | underlying_type, |
| 12530 | size_in_bits, |
| 12531 | align_in_bits, |
| 12532 | fields_tuple, |
| 12533 | ); |
| 12534 | } |
| 12535 | |
| 12536 | pub fn debugEnumerationType( |
| 12537 | self: *Builder, |
| 12538 | name: String, |
| 12539 | file: Metadata, |
| 12540 | scope: Metadata, |
| 12541 | line: u32, |
| 12542 | underlying_type: Metadata, |
| 12543 | size_in_bits: u64, |
| 12544 | align_in_bits: u64, |
| 12545 | fields_tuple: Metadata, |
| 12546 | ) Allocator.Error!Metadata { |
| 12547 | try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); |
| 12548 | const metadata_name = try self.metadataString(name); |
| 12549 | return self.debugEnumerationTypeAssumeCapacity( |
| 12550 | metadata_name, |
| 12551 | file, |
| 12552 | scope, |
| 12553 | line, |
| 12554 | underlying_type, |
| 12555 | size_in_bits, |
| 12556 | align_in_bits, |
| 12557 | fields_tuple, |
| 12558 | ); |
| 12559 | } |
| 12560 | |
| 12561 | pub fn debugArrayType( |
| 12562 | self: *Builder, |
| 12563 | name: String, |
| 12564 | file: Metadata, |
| 12565 | scope: Metadata, |
| 12566 | line: u32, |
| 12567 | underlying_type: Metadata, |
| 12568 | size_in_bits: u64, |
| 12569 | align_in_bits: u64, |
| 12570 | fields_tuple: Metadata, |
| 12571 | ) Allocator.Error!Metadata { |
| 12572 | try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); |
| 12573 | const metadata_name = try self.metadataString(name); |
| 12574 | return self.debugArrayTypeAssumeCapacity( |
| 12575 | metadata_name, |
| 12576 | file, |
| 12577 | scope, |
| 12578 | line, |
| 12579 | underlying_type, |
| 12580 | size_in_bits, |
| 12581 | align_in_bits, |
| 12582 | fields_tuple, |
| 12583 | ); |
| 12584 | } |
| 12585 | |
| 12586 | pub fn debugPointerType( |
| 12587 | self: *Builder, |
| 12588 | name: String, |
| 12589 | file: Metadata, |
| 12590 | scope: Metadata, |
| 12591 | line: u32, |
| 12592 | underlying_type: Metadata, |
| 12593 | size_in_bits: u64, |
| 12594 | align_in_bits: u64, |
| 12595 | offset_in_bits: u64, |
| 12596 | ) Allocator.Error!Metadata { |
| 12597 | try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0); |
| 12598 | const metadata_name = try self.metadataString(name); |
| 12599 | return self.debugPointerTypeAssumeCapacity( |
| 12600 | metadata_name, |
| 12601 | file, |
| 12602 | scope, |
| 12603 | line, |
| 12604 | underlying_type, |
| 12605 | size_in_bits, |
| 12606 | align_in_bits, |
| 12607 | offset_in_bits, |
| 12608 | ); |
| 12609 | } |
| 12610 | |
| 12611 | pub fn debugMemberType( |
| 12612 | self: *Builder, |
| 12613 | name: String, |
| 12614 | file: Metadata, |
| 12615 | scope: Metadata, |
| 12616 | line: u32, |
| 12617 | underlying_type: Metadata, |
| 12618 | size_in_bits: u64, |
| 12619 | align_in_bits: u64, |
| 12620 | offset_in_bits: u64, |
| 12621 | ) Allocator.Error!Metadata { |
| 12622 | try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0); |
| 12623 | const metadata_name = try self.metadataString(name); |
| 12624 | return self.debugMemberTypeAssumeCapacity( |
| 12625 | metadata_name, |
| 12626 | file, |
| 12627 | scope, |
| 12628 | line, |
| 12629 | underlying_type, |
| 12630 | size_in_bits, |
| 12631 | align_in_bits, |
| 12632 | offset_in_bits, |
| 12633 | ); |
| 12634 | } |
| 12635 | |
| 12636 | pub fn debugSubroutineType( |
| 12637 | self: *Builder, |
| 12638 | types_tuple: Metadata, |
| 12639 | ) Allocator.Error!Metadata { |
| 12640 | try self.ensureUnusedMetadataCapacity(1, Metadata.SubroutineType, 0); |
| 12641 | return self.debugSubroutineTypeAssumeCapacity(types_tuple); |
| 12642 | } |
| 12643 | |
| 12644 | pub fn debugEnumerator( |
| 12645 | self: *Builder, |
| 12646 | name: String, |
| 12647 | unsigned: bool, |
| 12648 | bit_width: u32, |
| 12649 | value: std.math.big.int.Const, |
| 12650 | ) Allocator.Error!Metadata { |
| 12651 | std.debug.assert(!(unsigned and !value.positive)); |
| 12652 | try self.ensureUnusedMetadataCapacity(1, Metadata.Enumerator, 0); |
| 12653 | try self.metadata_limbs.ensureUnusedCapacity(self.gpa, value.limbs.len); |
| 12654 | const metadata_name = try self.metadataString(name); |
| 12655 | return self.debugEnumeratorAssumeCapacity(metadata_name, unsigned, bit_width, value); |
| 12656 | } |
| 12657 | |
| 12658 | pub fn debugSubrange( |
| 12659 | self: *Builder, |
| 12660 | lower_bound: Metadata, |
| 12661 | count: Metadata, |
| 12662 | ) Allocator.Error!Metadata { |
| 12663 | try self.ensureUnusedMetadataCapacity(1, Metadata.Subrange, 0); |
| 12664 | return self.debugSubrangeAssumeCapacity(lower_bound, count); |
| 12665 | } |
| 12666 | |
| 12667 | pub fn debugExpression( |
| 12668 | self: *Builder, |
| 12669 | elements: []const u32, |
| 12670 | ) Allocator.Error!Metadata { |
| 12671 | try self.ensureUnusedMetadataCapacity(1, Metadata.Expression, elements.len * @sizeOf(u32)); |
| 12672 | return self.debugExpressionAssumeCapacity(elements); |
| 12673 | } |
| 12674 | |
| 12675 | pub fn debugTuple( |
| 12676 | self: *Builder, |
| 12677 | elements: []const Metadata, |
| 12678 | ) Allocator.Error!Metadata { |
| 12679 | try self.ensureUnusedMetadataCapacity(1, Metadata.Tuple, elements.len * @sizeOf(Metadata)); |
| 12680 | return self.debugTupleAssumeCapacity(elements); |
| 12681 | } |
| 12682 | |
| 12683 | pub fn debugModuleFlag( |
| 12684 | self: *Builder, |
| 12685 | behaviour: Metadata, |
| 12686 | name: String, |
| 12687 | constant: Metadata, |
| 12688 | ) Allocator.Error!Metadata { |
| 12689 | try self.ensureUnusedMetadataCapacity(1, Metadata.ModuleFlag, 0); |
| 12690 | const metadata_name = try self.metadataString(name); |
| 12691 | return self.debugModuleFlagAssumeCapacity(behaviour, metadata_name, constant); |
| 12692 | } |
| 12693 | |
| 12694 | pub fn debugLocalVar( |
| 12695 | self: *Builder, |
| 12696 | name: String, |
| 12697 | file: Metadata, |
| 12698 | scope: Metadata, |
| 12699 | line: u32, |
| 12700 | ty: Metadata, |
| 12701 | ) Allocator.Error!Metadata { |
| 12702 | try self.ensureUnusedMetadataCapacity(1, Metadata.LocalVar, 0); |
| 12703 | const metadata_name = try self.metadataString(name); |
| 12704 | return self.debugLocalVarAssumeCapacity(metadata_name, file, scope, line, ty); |
| 12705 | } |
| 12706 | |
| 12707 | pub fn debugParameter( |
| 12708 | self: *Builder, |
| 12709 | name: String, |
| 12710 | file: Metadata, |
| 12711 | scope: Metadata, |
| 12712 | line: u32, |
| 12713 | ty: Metadata, |
| 12714 | arg_no: u32, |
| 12715 | ) Allocator.Error!Metadata { |
| 12716 | try self.ensureUnusedMetadataCapacity(1, Metadata.Parameter, 0); |
| 12717 | const metadata_name = try self.metadataString(name); |
| 12718 | return self.debugParameterAssumeCapacity(metadata_name, file, scope, line, ty, arg_no); |
| 12719 | } |
| 12720 | |
| 12721 | pub fn debugGlobalVar( |
| 12722 | self: *Builder, |
| 12723 | name: String, |
| 12724 | linkage_name: String, |
| 12725 | file: Metadata, |
| 12726 | scope: Metadata, |
| 12727 | line: u32, |
| 12728 | ty: Metadata, |
| 12729 | variable: Variable.Index, |
| 12730 | flags: Metadata.GlobalVar.Flags, |
| 12731 | ) Allocator.Error!Metadata { |
| 12732 | try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVar, 0); |
| 12733 | const metadata_name = try self.metadataString(name); |
| 12734 | const metadata_linkage_name = try self.metadataString(linkage_name); |
| 12735 | return self.debugGlobalVarAssumeCapacity( |
| 12736 | metadata_name, |
| 12737 | metadata_linkage_name, |
| 12738 | file, |
| 12739 | scope, |
| 12740 | line, |
| 12741 | ty, |
| 12742 | variable, |
| 12743 | flags, |
| 12744 | ); |
| 12745 | } |
| 12746 | |
| 12747 | pub fn debugGlobalVarExpression( |
| 12748 | self: *Builder, |
| 12749 | variable: Metadata, |
| 12750 | expression: Metadata, |
| 12751 | ) Allocator.Error!Metadata { |
| 12752 | try self.ensureUnusedMetadataCapacity(1, Metadata.GlobalVarExpression, 0); |
| 12753 | return self.debugGlobalVarExpressionAssumeCapacity(variable, expression); |
| 12754 | } |
| 12755 | |
| 12756 | pub fn debugConstant(self: *Builder, value: Constant) Allocator.Error!Metadata { |
| 12757 | try self.ensureUnusedMetadataCapacity(1, NoExtra, 0); |
| 12758 | return self.debugConstantAssumeCapacity(value); |
| 12759 | } |
| 12760 | |
| 12761 | pub fn debugForwardReferenceSetType(self: *Builder, fwd_ref: Metadata, ty: Metadata) void { |
| 12762 | std.debug.assert( |
| 12763 | @intFromEnum(fwd_ref) >= Metadata.first_forward_reference and |
| 12764 | @intFromEnum(fwd_ref) <= Metadata.first_local_metadata, |
| 12765 | ); |
| 12766 | const index = @intFromEnum(fwd_ref) - Metadata.first_forward_reference; |
| 12767 | self.metadata_forward_references.items[index] = ty; |
| 12768 | } |
| 12769 | |
| 12770 | fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata { |
| 12771 | const Key = struct { |
| 12772 | tag: Metadata.Tag, |
| 12773 | value: @TypeOf(value), |
| 12774 | }; |
| 12775 | const Adapter = struct { |
| 12776 | builder: *const Builder, |
| 12777 | pub fn hash(_: @This(), key: Key) u32 { |
| 12778 | var hasher = std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(key.tag))); |
| 12779 | inline for (std.meta.fields(@TypeOf(value))) |field| { |
| 12780 | hasher.update(std.mem.asBytes(&@field(key.value, field.name))); |
| 12781 | } |
| 12782 | return @truncate(hasher.final()); |
| 12783 | } |
| 12784 | |
| 12785 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 12786 | if (lhs_key.tag != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 12787 | const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; |
| 12788 | const rhs_extra = ctx.builder.metadataExtraData(@TypeOf(value), rhs_data); |
| 12789 | inline for (std.meta.fields(@TypeOf(value))) |field| { |
| 12790 | const lhs = @field(lhs_key.value, field.name); |
| 12791 | const rhs = @field(rhs_extra, field.name); |
| 12792 | if (lhs != rhs) return false; |
| 12793 | } |
| 12794 | return true; |
| 12795 | } |
| 12796 | }; |
| 12797 | |
| 12798 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 12799 | Key{ .tag = tag, .value = value }, |
| 12800 | Adapter{ .builder = self }, |
| 12801 | ); |
| 12802 | |
| 12803 | if (!gop.found_existing) { |
| 12804 | gop.key_ptr.* = {}; |
| 12805 | gop.value_ptr.* = {}; |
| 12806 | self.metadata_items.appendAssumeCapacity(.{ |
| 12807 | .tag = tag, |
| 12808 | .data = self.addMetadataExtraAssumeCapacity(value), |
| 12809 | }); |
| 12810 | } |
| 12811 | return @enumFromInt(gop.index); |
| 12812 | } |
| 12813 | |
| 12814 | fn debugNamedAssumeCapacity(self: *Builder, name: String, operands: []const Metadata) void { |
| 12815 | const extra_index: u32 = @intCast(self.metadata_extra.items.len); |
| 12816 | self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(operands)); |
| 12817 | |
| 12818 | const gop = self.metadata_named.getOrPutAssumeCapacity(name); |
| 12819 | gop.value_ptr.* = .{ |
| 12820 | .index = extra_index, |
| 12821 | .len = @intCast(operands.len), |
| 12822 | }; |
| 12823 | } |
| 12824 | |
| 12825 | pub fn debugNoneAssumeCapacity(self: *Builder) Metadata { |
| 12826 | return self.metadataSimpleAssumeCapacity(.none, .{}); |
| 12827 | } |
| 12828 | |
| 12829 | fn debugFileAssumeCapacity(self: *Builder, path: MetadataString, name: MetadataString) Metadata { |
| 12830 | return self.metadataSimpleAssumeCapacity(.file, Metadata.File{ |
| 12831 | .path = path, |
| 12832 | .name = name, |
| 12833 | }); |
| 12834 | } |
| 12835 | |
| 12836 | pub fn debugCompileUnitAssumeCapacity( |
| 12837 | self: *Builder, |
| 12838 | file: Metadata, |
| 12839 | producer: MetadataString, |
| 12840 | enums: Metadata, |
| 12841 | globals: Metadata, |
| 12842 | flags: Metadata.CompileUnit.Flags, |
| 12843 | ) Metadata { |
| 12844 | return self.metadataSimpleAssumeCapacity( |
| 12845 | if (flags.optimized) .@"compile_unit optimized" else .compile_unit, |
| 12846 | Metadata.CompileUnit{ |
| 12847 | .file = file, |
| 12848 | .producer = producer, |
| 12849 | .enums = enums, |
| 12850 | .globals = globals, |
| 12851 | }, |
| 12852 | ); |
| 12853 | } |
| 12854 | |
| 12855 | fn debugSubprogramAssumeCapacity( |
| 12856 | self: *Builder, |
| 12857 | file: Metadata, |
| 12858 | name: MetadataString, |
| 12859 | linkage_name: MetadataString, |
| 12860 | line: u32, |
| 12861 | scope_line: u32, |
| 12862 | ty: Metadata, |
| 12863 | flags: Metadata.Subprogram.Flags, |
| 12864 | compile_unit: Metadata, |
| 12865 | ) Metadata { |
| 12866 | const tag: Metadata.Tag = blk: { |
| 12867 | var int: u3 = 0; |
| 12868 | if (flags.optimized) int |= 0b1; |
| 12869 | if (flags.local) int |= 0b10; |
| 12870 | if (flags.definition) int |= 0b100; |
| 12871 | break :blk switch (int) { |
| 12872 | 0 => .subprogram, |
| 12873 | 0b1 => .@"subprogram optimized", |
| 12874 | 0b10 => .@"subprogram local", |
| 12875 | 0b100 => .@"subprogram definition", |
| 12876 | 0b011 => .@"subprogram optimized local", |
| 12877 | 0b111 => .@"subprogram optimized local definition", |
| 12878 | 0b101 => .@"subprogram optimized definition", |
| 12879 | 0b110 => .@"subprogram local definition", |
| 12880 | }; |
| 12881 | }; |
| 12882 | return self.metadataSimpleAssumeCapacity(tag, Metadata.Subprogram{ |
| 12883 | .file = file, |
| 12884 | .name = name, |
| 12885 | .linkage_name = linkage_name, |
| 12886 | .line = line, |
| 12887 | .scope_line = scope_line, |
| 12888 | .ty = ty, |
| 12889 | .debug_info_flags = flags.debug_info_flags, |
| 12890 | .compile_unit = compile_unit, |
| 12891 | }); |
| 12892 | } |
| 12893 | |
| 12894 | fn debugLexicalBlockAssumeCapacity(self: *Builder, file: Metadata, scope: Metadata, line: u32, column: u32) Metadata { |
| 12895 | return self.metadataSimpleAssumeCapacity(.lexical_block, Metadata.LexicalBlock{ |
| 12896 | .file = file, |
| 12897 | .scope = scope, |
| 12898 | .line = line, |
| 12899 | .column = column, |
| 12900 | }); |
| 12901 | } |
| 12902 | |
| 12903 | fn debugLocationAssumeCapacity(self: *Builder, scope: Metadata, line: u32, column: u32, inlined_at: Metadata) Metadata { |
| 12904 | return self.metadataSimpleAssumeCapacity(.location, Metadata.Location{ |
| 12905 | .scope = scope, |
| 12906 | .line = line, |
| 12907 | .column = column, |
| 12908 | .inlined_at = inlined_at, |
| 12909 | }); |
| 12910 | } |
| 12911 | |
| 12912 | fn debugBoolTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12913 | return self.metadataSimpleAssumeCapacity(.basic_bool_type, Metadata.BasicType{ |
| 12914 | .name = name, |
| 12915 | .size_in_bits_lo = @truncate(size_in_bits), |
| 12916 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 12917 | }); |
| 12918 | } |
| 12919 | |
| 12920 | fn debugUnsignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12921 | return self.metadataSimpleAssumeCapacity(.basic_unsigned_type, Metadata.BasicType{ |
| 12922 | .name = name, |
| 12923 | .size_in_bits_lo = @truncate(size_in_bits), |
| 12924 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 12925 | }); |
| 12926 | } |
| 12927 | |
| 12928 | fn debugSignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12929 | return self.metadataSimpleAssumeCapacity(.basic_signed_type, Metadata.BasicType{ |
| 12930 | .name = name, |
| 12931 | .size_in_bits_lo = @truncate(size_in_bits), |
| 12932 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 12933 | }); |
| 12934 | } |
| 12935 | |
| 12936 | fn debugFloatTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12937 | return self.metadataSimpleAssumeCapacity(.basic_float_type, Metadata.BasicType{ |
| 12938 | .name = name, |
| 12939 | .size_in_bits_lo = @truncate(size_in_bits), |
| 12940 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 12941 | }); |
| 12942 | } |
| 12943 | |
| 12944 | fn debugForwardReferenceAssumeCapacity(self: *Builder) Metadata { |
| 12945 | const index = Metadata.first_forward_reference + self.metadata_forward_references.items.len; |
| 12946 | self.metadata_forward_references.appendAssumeCapacity(.none); |
| 12947 | return @enumFromInt(index); |
| 12948 | } |
| 12949 | |
| 12950 | fn debugStructTypeAssumeCapacity( |
| 12951 | self: *Builder, |
| 12952 | name: MetadataString, |
| 12953 | file: Metadata, |
| 12954 | scope: Metadata, |
| 12955 | line: u32, |
| 12956 | underlying_type: Metadata, |
| 12957 | size_in_bits: u64, |
| 12958 | align_in_bits: u64, |
| 12959 | fields_tuple: Metadata, |
| 12960 | ) Metadata { |
| 12961 | return self.debugCompositeTypeAssumeCapacity( |
| 12962 | .composite_struct_type, |
| 12963 | name, |
| 12964 | file, |
| 12965 | scope, |
| 12966 | line, |
| 12967 | underlying_type, |
| 12968 | size_in_bits, |
| 12969 | align_in_bits, |
| 12970 | fields_tuple, |
| 12971 | ); |
| 12972 | } |
| 12973 | |
| 12974 | fn debugUnionTypeAssumeCapacity( |
| 12975 | self: *Builder, |
| 12976 | name: MetadataString, |
| 12977 | file: Metadata, |
| 12978 | scope: Metadata, |
| 12979 | line: u32, |
| 12980 | underlying_type: Metadata, |
| 12981 | size_in_bits: u64, |
| 12982 | align_in_bits: u64, |
| 12983 | fields_tuple: Metadata, |
| 12984 | ) Metadata { |
| 12985 | return self.debugCompositeTypeAssumeCapacity( |
| 12986 | .composite_union_type, |
| 12987 | name, |
| 12988 | file, |
| 12989 | scope, |
| 12990 | line, |
| 12991 | underlying_type, |
| 12992 | size_in_bits, |
| 12993 | align_in_bits, |
| 12994 | fields_tuple, |
| 12995 | ); |
| 12996 | } |
| 12997 | |
| 12998 | fn debugEnumerationTypeAssumeCapacity( |
| 12999 | self: *Builder, |
| 13000 | name: MetadataString, |
| 13001 | file: Metadata, |
| 13002 | scope: Metadata, |
| 13003 | line: u32, |
| 13004 | underlying_type: Metadata, |
| 13005 | size_in_bits: u64, |
| 13006 | align_in_bits: u64, |
| 13007 | fields_tuple: Metadata, |
| 13008 | ) Metadata { |
| 13009 | return self.debugCompositeTypeAssumeCapacity( |
| 13010 | .composite_enumeration_type, |
| 13011 | name, |
| 13012 | file, |
| 13013 | scope, |
| 13014 | line, |
| 13015 | underlying_type, |
| 13016 | size_in_bits, |
| 13017 | align_in_bits, |
| 13018 | fields_tuple, |
| 13019 | ); |
| 13020 | } |
| 13021 | |
| 13022 | fn debugArrayTypeAssumeCapacity( |
| 13023 | self: *Builder, |
| 13024 | name: MetadataString, |
| 13025 | file: Metadata, |
| 13026 | scope: Metadata, |
| 13027 | line: u32, |
| 13028 | underlying_type: Metadata, |
| 13029 | size_in_bits: u64, |
| 13030 | align_in_bits: u64, |
| 13031 | fields_tuple: Metadata, |
| 13032 | ) Metadata { |
| 13033 | return self.debugCompositeTypeAssumeCapacity( |
| 13034 | .composite_array_type, |
| 13035 | name, |
| 13036 | file, |
| 13037 | scope, |
| 13038 | line, |
| 13039 | underlying_type, |
| 13040 | size_in_bits, |
| 13041 | align_in_bits, |
| 13042 | fields_tuple, |
| 13043 | ); |
| 13044 | } |
| 13045 | |
| 13046 | fn debugCompositeTypeAssumeCapacity( |
| 13047 | self: *Builder, |
| 13048 | tag: Metadata.Tag, |
| 13049 | name: MetadataString, |
| 13050 | file: Metadata, |
| 13051 | scope: Metadata, |
| 13052 | line: u32, |
| 13053 | underlying_type: Metadata, |
| 13054 | size_in_bits: u64, |
| 13055 | align_in_bits: u64, |
| 13056 | fields_tuple: Metadata, |
| 13057 | ) Metadata { |
| 13058 | const Key = struct { |
| 13059 | tag: Metadata.Tag, |
| 13060 | name: MetadataString, |
| 13061 | file: Metadata, |
| 13062 | scope: Metadata, |
| 13063 | line: u32, |
| 13064 | underlying_type: Metadata, |
| 13065 | size_in_bits: u64, |
| 13066 | align_in_bits: u64, |
| 13067 | fields_tuple: Metadata, |
| 13068 | }; |
| 13069 | const Adapter = struct { |
| 13070 | builder: *const Builder, |
| 13071 | pub fn hash(_: @This(), key: Key) u32 { |
| 13072 | var hasher = std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(key.tag))); |
| 13073 | hasher.update(std.mem.asBytes(&key.name)); |
| 13074 | hasher.update(std.mem.asBytes(&key.file)); |
| 13075 | hasher.update(std.mem.asBytes(&key.scope)); |
| 13076 | hasher.update(std.mem.asBytes(&key.line)); |
| 13077 | hasher.update(std.mem.asBytes(&key.underlying_type)); |
| 13078 | hasher.update(std.mem.asBytes(&key.size_in_bits)); |
| 13079 | hasher.update(std.mem.asBytes(&key.align_in_bits)); |
| 13080 | hasher.update(std.mem.asBytes(&key.fields_tuple)); |
| 13081 | return @truncate(hasher.final()); |
| 13082 | } |
| 13083 | |
| 13084 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 13085 | if (lhs_key.tag != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 13086 | const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; |
| 13087 | const rhs_extra = ctx.builder.metadataExtraData(Metadata.CompositeType, rhs_data); |
| 13088 | const rhs_size_in_bits = @as(u64, rhs_extra.size_in_bits_lo) | @as(u64, rhs_extra.size_in_bits_hi) << 32; |
| 13089 | const rhs_align_in_bits = @as(u64, rhs_extra.align_in_bits_lo) | @as(u64, rhs_extra.align_in_bits_hi) << 32; |
| 13090 | return lhs_key.name == rhs_extra.name and |
| 13091 | lhs_key.file == rhs_extra.file and |
| 13092 | lhs_key.scope == rhs_extra.scope and |
| 13093 | lhs_key.line == rhs_extra.line and |
| 13094 | lhs_key.underlying_type == rhs_extra.underlying_type and |
| 13095 | lhs_key.size_in_bits == rhs_size_in_bits and |
| 13096 | lhs_key.align_in_bits == rhs_align_in_bits and |
| 13097 | lhs_key.fields_tuple == rhs_extra.fields_tuple; |
| 13098 | } |
| 13099 | }; |
| 13100 | |
| 13101 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 13102 | Key{ |
| 13103 | .tag = tag, |
| 13104 | .name = name, |
| 13105 | .file = file, |
| 13106 | .scope = scope, |
| 13107 | .line = line, |
| 13108 | .underlying_type = underlying_type, |
| 13109 | .size_in_bits = size_in_bits, |
| 13110 | .align_in_bits = align_in_bits, |
| 13111 | .fields_tuple = fields_tuple, |
| 13112 | }, |
| 13113 | Adapter{ .builder = self }, |
| 13114 | ); |
| 13115 | |
| 13116 | if (!gop.found_existing) { |
| 13117 | gop.key_ptr.* = {}; |
| 13118 | gop.value_ptr.* = {}; |
| 13119 | self.metadata_items.appendAssumeCapacity(.{ |
| 13120 | .tag = tag, |
| 13121 | .data = self.addMetadataExtraAssumeCapacity(Metadata.CompositeType{ |
| 13122 | .name = name, |
| 13123 | .file = file, |
| 13124 | .scope = scope, |
| 13125 | .line = line, |
| 13126 | .underlying_type = underlying_type, |
| 13127 | .size_in_bits_lo = @truncate(size_in_bits), |
| 13128 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 13129 | .align_in_bits_lo = @truncate(align_in_bits), |
| 13130 | .align_in_bits_hi = @truncate(align_in_bits >> 32), |
| 13131 | .fields_tuple = fields_tuple, |
| 13132 | }), |
| 13133 | }); |
| 13134 | } |
| 13135 | return @enumFromInt(gop.index); |
| 13136 | } |
| 13137 | |
| 13138 | fn debugPointerTypeAssumeCapacity( |
| 13139 | self: *Builder, |
| 13140 | name: MetadataString, |
| 13141 | file: Metadata, |
| 13142 | scope: Metadata, |
| 13143 | line: u32, |
| 13144 | underlying_type: Metadata, |
| 13145 | size_in_bits: u64, |
| 13146 | align_in_bits: u64, |
| 13147 | offset_in_bits: u64, |
| 13148 | ) Metadata { |
| 13149 | return self.metadataSimpleAssumeCapacity(.derived_pointer_type, Metadata.DerivedType{ |
| 13150 | .name = name, |
| 13151 | .file = file, |
| 13152 | .scope = scope, |
| 13153 | .line = line, |
| 13154 | .underlying_type = underlying_type, |
| 13155 | .size_in_bits_lo = @truncate(size_in_bits), |
| 13156 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 13157 | .align_in_bits_lo = @truncate(align_in_bits), |
| 13158 | .align_in_bits_hi = @truncate(align_in_bits >> 32), |
| 13159 | .offset_in_bits_lo = @truncate(offset_in_bits), |
| 13160 | .offset_in_bits_hi = @truncate(offset_in_bits >> 32), |
| 13161 | }); |
| 13162 | } |
| 13163 | |
| 13164 | fn debugMemberTypeAssumeCapacity( |
| 13165 | self: *Builder, |
| 13166 | name: MetadataString, |
| 13167 | file: Metadata, |
| 13168 | scope: Metadata, |
| 13169 | line: u32, |
| 13170 | underlying_type: Metadata, |
| 13171 | size_in_bits: u64, |
| 13172 | align_in_bits: u64, |
| 13173 | offset_in_bits: u64, |
| 13174 | ) Metadata { |
| 13175 | return self.metadataSimpleAssumeCapacity(.derived_member_type, Metadata.DerivedType{ |
| 13176 | .name = name, |
| 13177 | .file = file, |
| 13178 | .scope = scope, |
| 13179 | .line = line, |
| 13180 | .underlying_type = underlying_type, |
| 13181 | .size_in_bits_lo = @truncate(size_in_bits), |
| 13182 | .size_in_bits_hi = @truncate(size_in_bits >> 32), |
| 13183 | .align_in_bits_lo = @truncate(align_in_bits), |
| 13184 | .align_in_bits_hi = @truncate(align_in_bits >> 32), |
| 13185 | .offset_in_bits_lo = @truncate(offset_in_bits), |
| 13186 | .offset_in_bits_hi = @truncate(offset_in_bits >> 32), |
| 13187 | }); |
| 13188 | } |
| 13189 | |
| 13190 | fn debugSubroutineTypeAssumeCapacity( |
| 13191 | self: *Builder, |
| 13192 | types_tuple: Metadata, |
| 13193 | ) Metadata { |
| 13194 | return self.metadataSimpleAssumeCapacity(.subroutine_type, Metadata.SubroutineType{ |
| 13195 | .types_tuple = types_tuple, |
| 13196 | }); |
| 13197 | } |
| 13198 | |
| 13199 | fn debugEnumeratorAssumeCapacity( |
| 13200 | self: *Builder, |
| 13201 | name: MetadataString, |
| 13202 | unsigned: bool, |
| 13203 | bit_width: u32, |
| 13204 | value: std.math.big.int.Const, |
| 13205 | ) Metadata { |
| 13206 | const Key = struct { |
| 13207 | tag: Metadata.Tag, |
| 13208 | name: MetadataString, |
| 13209 | bit_width: u32, |
| 13210 | value: std.math.big.int.Const, |
| 13211 | }; |
| 13212 | const Adapter = struct { |
| 13213 | builder: *const Builder, |
| 13214 | pub fn hash(_: @This(), key: Key) u32 { |
| 13215 | var hasher = std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(key.tag))); |
| 13216 | hasher.update(std.mem.asBytes(&key.name)); |
| 13217 | hasher.update(std.mem.asBytes(&key.bit_width)); |
| 13218 | hasher.update(std.mem.sliceAsBytes(key.value.limbs)); |
| 13219 | return @truncate(hasher.final()); |
| 13220 | } |
| 13221 | |
| 13222 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 13223 | if (lhs_key.tag != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 13224 | const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; |
| 13225 | const rhs_extra = ctx.builder.metadataExtraData(Metadata.Enumerator, rhs_data); |
| 13226 | const limbs = ctx.builder.metadata_limbs |
| 13227 | .items[rhs_extra.limbs_index..][0..rhs_extra.limbs_len]; |
| 13228 | const rhs_value = std.math.big.int.Const{ |
| 13229 | .limbs = limbs, |
| 13230 | .positive = lhs_key.value.positive, |
| 13231 | }; |
| 13232 | return lhs_key.name == rhs_extra.name and |
| 13233 | lhs_key.bit_width == rhs_extra.bit_width and |
| 13234 | lhs_key.value.eql(rhs_value); |
| 13235 | } |
| 13236 | }; |
| 13237 | |
| 13238 | const tag: Metadata.Tag = if (unsigned) |
| 13239 | .enumerator_unsigned |
| 13240 | else if (value.positive) .enumerator_signed_positive else .enumerator_signed_negative; |
| 13241 | |
| 13242 | std.debug.assert(!(tag == .enumerator_unsigned and !value.positive)); |
| 13243 | |
| 13244 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 13245 | Key{ |
| 13246 | .tag = tag, |
| 13247 | .name = name, |
| 13248 | .bit_width = bit_width, |
| 13249 | .value = value, |
| 13250 | }, |
| 13251 | Adapter{ .builder = self }, |
| 13252 | ); |
| 13253 | |
| 13254 | if (!gop.found_existing) { |
| 13255 | gop.key_ptr.* = {}; |
| 13256 | gop.value_ptr.* = {}; |
| 13257 | self.metadata_items.appendAssumeCapacity(.{ |
| 13258 | .tag = tag, |
| 13259 | .data = self.addMetadataExtraAssumeCapacity(Metadata.Enumerator{ |
| 13260 | .name = name, |
| 13261 | .bit_width = bit_width, |
| 13262 | .limbs_index = @intCast(self.metadata_limbs.items.len), |
| 13263 | .limbs_len = @intCast(value.limbs.len), |
| 13264 | }), |
| 13265 | }); |
| 13266 | self.metadata_limbs.appendSliceAssumeCapacity(value.limbs); |
| 13267 | } |
| 13268 | return @enumFromInt(gop.index); |
| 13269 | } |
| 13270 | |
| 13271 | fn debugSubrangeAssumeCapacity( |
| 13272 | self: *Builder, |
| 13273 | lower_bound: Metadata, |
| 13274 | count: Metadata, |
| 13275 | ) Metadata { |
| 13276 | return self.metadataSimpleAssumeCapacity(.subrange, Metadata.Subrange{ |
| 13277 | .lower_bound = lower_bound, |
| 13278 | .count = count, |
| 13279 | }); |
| 13280 | } |
| 13281 | |
| 13282 | fn debugExpressionAssumeCapacity( |
| 13283 | self: *Builder, |
| 13284 | elements: []const u32, |
| 13285 | ) Metadata { |
| 13286 | const Key = struct { |
| 13287 | elements: []const u32, |
| 13288 | }; |
| 13289 | const Adapter = struct { |
| 13290 | builder: *const Builder, |
| 13291 | pub fn hash(_: @This(), key: Key) u32 { |
| 13292 | var hasher = comptime std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(Metadata.Tag.expression))); |
| 13293 | hasher.update(std.mem.sliceAsBytes(key.elements)); |
| 13294 | return @truncate(hasher.final()); |
| 13295 | } |
| 13296 | |
| 13297 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 13298 | if (Metadata.Tag.expression != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 13299 | const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; |
| 13300 | var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Expression, rhs_data); |
| 13301 | return std.mem.eql( |
| 13302 | u32, |
| 13303 | lhs_key.elements, |
| 13304 | rhs_extra.trail.next(rhs_extra.data.elements_len, u32, ctx.builder), |
| 13305 | ); |
| 13306 | } |
| 13307 | }; |
| 13308 | |
| 13309 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 13310 | Key{ .elements = elements }, |
| 13311 | Adapter{ .builder = self }, |
| 13312 | ); |
| 13313 | |
| 13314 | if (!gop.found_existing) { |
| 13315 | gop.key_ptr.* = {}; |
| 13316 | gop.value_ptr.* = {}; |
| 13317 | self.metadata_items.appendAssumeCapacity(.{ |
| 13318 | .tag = .expression, |
| 13319 | .data = self.addMetadataExtraAssumeCapacity(Metadata.Expression{ |
| 13320 | .elements_len = @intCast(elements.len), |
| 13321 | }), |
| 13322 | }); |
| 13323 | self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements)); |
| 13324 | } |
| 13325 | return @enumFromInt(gop.index); |
| 13326 | } |
| 13327 | |
| 13328 | fn debugTupleAssumeCapacity( |
| 13329 | self: *Builder, |
| 13330 | elements: []const Metadata, |
| 13331 | ) Metadata { |
| 13332 | const Key = struct { |
| 13333 | elements: []const Metadata, |
| 13334 | }; |
| 13335 | const Adapter = struct { |
| 13336 | builder: *const Builder, |
| 13337 | pub fn hash(_: @This(), key: Key) u32 { |
| 13338 | var hasher = comptime std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(Metadata.Tag.tuple))); |
| 13339 | hasher.update(std.mem.sliceAsBytes(key.elements)); |
| 13340 | return @truncate(hasher.final()); |
| 13341 | } |
| 13342 | |
| 13343 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 13344 | if (Metadata.Tag.tuple != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 13345 | const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; |
| 13346 | var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Tuple, rhs_data); |
| 13347 | return std.mem.eql( |
| 13348 | Metadata, |
| 13349 | lhs_key.elements, |
| 13350 | rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata, ctx.builder), |
| 13351 | ); |
| 13352 | } |
| 13353 | }; |
| 13354 | |
| 13355 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 13356 | Key{ .elements = elements }, |
| 13357 | Adapter{ .builder = self }, |
| 13358 | ); |
| 13359 | |
| 13360 | if (!gop.found_existing) { |
| 13361 | gop.key_ptr.* = {}; |
| 13362 | gop.value_ptr.* = {}; |
| 13363 | self.metadata_items.appendAssumeCapacity(.{ |
| 13364 | .tag = .tuple, |
| 13365 | .data = self.addMetadataExtraAssumeCapacity(Metadata.Tuple{ |
| 13366 | .elements_len = @intCast(elements.len), |
| 13367 | }), |
| 13368 | }); |
| 13369 | self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(elements)); |
| 13370 | } |
| 13371 | return @enumFromInt(gop.index); |
| 13372 | } |
| 13373 | |
| 13374 | fn debugModuleFlagAssumeCapacity( |
| 13375 | self: *Builder, |
| 13376 | behaviour: Metadata, |
| 13377 | name: MetadataString, |
| 13378 | constant: Metadata, |
| 13379 | ) Metadata { |
| 13380 | return self.metadataSimpleAssumeCapacity(.module_flag, Metadata.ModuleFlag{ |
| 13381 | .behaviour = behaviour, |
| 13382 | .name = name, |
| 13383 | .constant = constant, |
| 13384 | }); |
| 13385 | } |
| 13386 | |
| 13387 | fn debugLocalVarAssumeCapacity( |
| 13388 | self: *Builder, |
| 13389 | name: MetadataString, |
| 13390 | file: Metadata, |
| 13391 | scope: Metadata, |
| 13392 | line: u32, |
| 13393 | ty: Metadata, |
| 13394 | ) Allocator.Error!Metadata { |
| 13395 | return self.metadataSimpleAssumeCapacity(.local_var, Metadata.LocalVar{ |
| 13396 | .name = name, |
| 13397 | .file = file, |
| 13398 | .scope = scope, |
| 13399 | .line = line, |
| 13400 | .ty = ty, |
| 13401 | }); |
| 13402 | } |
| 13403 | |
| 13404 | fn debugParameterAssumeCapacity( |
| 13405 | self: *Builder, |
| 13406 | name: MetadataString, |
| 13407 | file: Metadata, |
| 13408 | scope: Metadata, |
| 13409 | line: u32, |
| 13410 | ty: Metadata, |
| 13411 | arg_no: u32, |
| 13412 | ) Allocator.Error!Metadata { |
| 13413 | return self.metadataSimpleAssumeCapacity(.parameter, Metadata.Parameter{ |
| 13414 | .name = name, |
| 13415 | .file = file, |
| 13416 | .scope = scope, |
| 13417 | .line = line, |
| 13418 | .ty = ty, |
| 13419 | .arg_no = arg_no, |
| 13420 | }); |
| 13421 | } |
| 13422 | |
| 13423 | fn debugGlobalVarAssumeCapacity( |
| 13424 | self: *Builder, |
| 13425 | name: MetadataString, |
| 13426 | linkage_name: MetadataString, |
| 13427 | file: Metadata, |
| 13428 | scope: Metadata, |
| 13429 | line: u32, |
| 13430 | ty: Metadata, |
| 13431 | variable: Variable.Index, |
| 13432 | flags: Metadata.GlobalVar.Flags, |
| 13433 | ) Allocator.Error!Metadata { |
| 13434 | return self.metadataSimpleAssumeCapacity( |
| 13435 | if (flags.local) .@"global_var local" else .global_var, |
| 13436 | Metadata.GlobalVar{ |
| 13437 | .name = name, |
| 13438 | .linkage_name = linkage_name, |
| 13439 | .file = file, |
| 13440 | .scope = scope, |
| 13441 | .line = line, |
| 13442 | .ty = ty, |
| 13443 | .variable = variable, |
| 13444 | }, |
| 13445 | ); |
| 13446 | } |
| 13447 | |
| 13448 | fn debugGlobalVarExpressionAssumeCapacity( |
| 13449 | self: *Builder, |
| 13450 | variable: Metadata, |
| 13451 | expression: Metadata, |
| 13452 | ) Metadata { |
| 13453 | return self.metadataSimpleAssumeCapacity(.global_var_expression, Metadata.GlobalVarExpression{ |
| 13454 | .variable = variable, |
| 13455 | .expression = expression, |
| 13456 | }); |
| 13457 | } |
| 13458 | |
| 13459 | fn debugConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata { |
| 13460 | const Adapter = struct { |
| 13461 | builder: *const Builder, |
| 13462 | pub fn hash(_: @This(), key: Constant) u32 { |
| 13463 | var hasher = comptime std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(Metadata.Tag.constant))); |
| 13464 | hasher.update(std.mem.asBytes(&key)); |
| 13465 | return @truncate(hasher.final()); |
| 13466 | } |
| 13467 | |
| 13468 | pub fn eql(ctx: @This(), lhs_key: Constant, _: void, rhs_index: usize) bool { |
| 13469 | if (Metadata.Tag.constant != ctx.builder.metadata_items.items(.tag)[rhs_index]) return false; |
| 13470 | const rhs_data: Constant = @enumFromInt(ctx.builder.metadata_items.items(.data)[rhs_index]); |
| 13471 | return rhs_data == lhs_key; |
| 13472 | } |
| 13473 | }; |
| 13474 | |
| 13475 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 13476 | constant, |
| 13477 | Adapter{ .builder = self }, |
| 13478 | ); |
| 13479 | |
| 13480 | if (!gop.found_existing) { |
| 13481 | gop.key_ptr.* = {}; |
| 13482 | gop.value_ptr.* = {}; |
| 13483 | self.metadata_items.appendAssumeCapacity(.{ |
| 13484 | .tag = .constant, |
| 13485 | .data = @intFromEnum(constant), |
| 13486 | }); |
| 13487 | } |
| 13488 | return @enumFromInt(gop.index); |
| 13489 | } |
| 13490 | |
| 12045 | 13491 | pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]const u32 { |
| 12046 | 13492 | const BitcodeWriter = bitcode_writer.BitcodeWriter(&.{ Type, FunctionAttributes }); |
| 12047 | 13493 | var bitcode = BitcodeWriter.init(allocator, &.{ |
| ... | ... | @@ -12977,6 +14423,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 12977 | 14423 | return @intCast(switch (value.unwrap()) { |
| 12978 | 14424 | .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(), |
| 12979 | 14425 | .constant => |constant| adapter.constant_adapter.getConstantIndex(constant), |
| 14426 | .metadata => unreachable, |
| 12980 | 14427 | }); |
| 12981 | 14428 | } |
| 12982 | 14429 | |