| ... | @@ -52,6 +52,17 @@ constant_items: std.MultiArrayList(Constant.Item), | ... | @@ -52,6 +52,17 @@ constant_items: std.MultiArrayList(Constant.Item), |
| 52 | constant_extra: std.ArrayListUnmanaged(u32), | 52 | constant_extra: std.ArrayListUnmanaged(u32), |
| 53 | constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb), | 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 | pub const expected_args_len = 16; | 66 | pub const expected_args_len = 16; |
| 56 | pub const expected_attrs_len = 16; | 67 | pub const expected_attrs_len = 16; |
| 57 | pub const expected_fields_len = 32; | 68 | pub const expected_fields_len = 32; |
| ... | @@ -6403,6 +6414,7 @@ pub const WipFunction = struct { | ... | @@ -6403,6 +6414,7 @@ pub const WipFunction = struct { |
| 6403 | @intFromEnum(instruction) | 6414 | @intFromEnum(instruction) |
| 6404 | ].toValue(), | 6415 | ].toValue(), |
| 6405 | .constant => |constant| constant.toValue(), | 6416 | .constant => |constant| constant.toValue(), |
| | 6417 | .metadata => |metadata| metadata.toValue(), |
| 6406 | }; | 6418 | }; |
| 6407 | } | 6419 | } |
| 6408 | } = .{ .items = try gpa.alloc(Instruction.Index, self.instructions.len) }; | 6420 | } = .{ .items = try gpa.alloc(Instruction.Index, self.instructions.len) }; |
| ... | @@ -7400,10 +7412,10 @@ pub const Constant = enum(u32) { | ... | @@ -7400,10 +7412,10 @@ pub const Constant = enum(u32) { |
| 7400 | false, | 7412 | false, |
| 7401 | true, | 7413 | true, |
| 7402 | none, | 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 | pub const Tag = enum(u7) { | 7420 | pub const Tag = enum(u7) { |
| 7409 | positive_integer, | 7421 | positive_integer, |
| ... | @@ -8189,22 +8201,27 @@ pub const Value = enum(u32) { | ... | @@ -8189,22 +8201,27 @@ pub const Value = enum(u32) { |
| 8189 | true = first_constant + @intFromEnum(Constant.true), | 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 | pub fn unwrap(self: Value) union(enum) { | 8207 | pub fn unwrap(self: Value) union(enum) { |
| 8195 | instruction: Function.Instruction.Index, | 8208 | instruction: Function.Instruction.Index, |
| 8196 | constant: Constant, | 8209 | constant: Constant, |
| | 8210 | metadata: Metadata, |
| 8197 | } { | 8211 | } { |
| 8198 | return if (@intFromEnum(self) < first_constant) | 8212 | return if (@intFromEnum(self) < first_constant) |
| 8199 | .{ .instruction = @enumFromInt(@intFromEnum(self)) } | 8213 | .{ .instruction = @enumFromInt(@intFromEnum(self)) } |
| | 8214 | else if (@intFromEnum(self) < first_metadata) |
| | 8215 | .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) } |
| 8200 | else | 8216 | else |
| 8201 | .{ .constant = @enumFromInt(@intFromEnum(self) - first_constant) }; | 8217 | .{ .metadata = @enumFromInt(@intFromEnum(self) - first_metadata) }; |
| 8202 | } | 8218 | } |
| 8203 | | 8219 | |
| 8204 | pub fn typeOfWip(self: Value, wip: *const WipFunction) Type { | 8220 | pub fn typeOfWip(self: Value, wip: *const WipFunction) Type { |
| 8205 | return switch (self.unwrap()) { | 8221 | return switch (self.unwrap()) { |
| 8206 | .instruction => |instruction| instruction.typeOfWip(wip), | 8222 | .instruction => |instruction| instruction.typeOfWip(wip), |
| 8207 | .constant => |constant| constant.typeOf(wip.builder), | 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,12 +8229,13 @@ pub const Value = enum(u32) { |
| 8212 | return switch (self.unwrap()) { | 8229 | return switch (self.unwrap()) { |
| 8213 | .instruction => |instruction| instruction.typeOf(function, builder), | 8230 | .instruction => |instruction| instruction.typeOf(function, builder), |
| 8214 | .constant => |constant| constant.typeOf(builder), | 8231 | .constant => |constant| constant.typeOf(builder), |
| | 8232 | .metadata => Type.metadata, |
| 8215 | }; | 8233 | }; |
| 8216 | } | 8234 | } |
| 8217 | | 8235 | |
| 8218 | pub fn toConst(self: Value) ?Constant { | 8236 | pub fn toConst(self: Value) ?Constant { |
| 8219 | return switch (self.unwrap()) { | 8237 | return switch (self.unwrap()) { |
| 8220 | .instruction => null, | 8238 | .instruction, .metadata => null, |
| 8221 | .constant => |constant| constant, | 8239 | .constant => |constant| constant, |
| 8222 | }; | 8240 | }; |
| 8223 | } | 8241 | } |
| ... | @@ -8243,6 +8261,7 @@ pub const Value = enum(u32) { | ... | @@ -8243,6 +8261,7 @@ pub const Value = enum(u32) { |
| 8243 | .constant = constant, | 8261 | .constant = constant, |
| 8244 | .builder = data.builder, | 8262 | .builder = data.builder, |
| 8245 | }, fmt_str, fmt_opts, writer), | 8263 | }, fmt_str, fmt_opts, writer), |
| | 8264 | .metadata => unreachable, |
| 8246 | } | 8265 | } |
| 8247 | } | 8266 | } |
| 8248 | pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(format) { | 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,11 +8272,239 @@ pub const Value = enum(u32) { |
| 8253 | return switch (self.unwrap()) { | 8272 | return switch (self.unwrap()) { |
| 8254 | .instruction => |instruction| instruction.toLlvm(wip), | 8273 | .instruction => |instruction| instruction.toLlvm(wip), |
| 8255 | .constant => |constant| constant.toLlvm(wip.builder), | 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 | pub const InitError = error{ | 8509 | pub const InitError = error{ |
| 8263 | InvalidLlvmTriple, | 8510 | InvalidLlvmTriple, |
| ... | @@ -8306,6 +8553,14 @@ pub fn init(options: Options) InitError!Builder { | ... | @@ -8306,6 +8553,14 @@ pub fn init(options: Options) InitError!Builder { |
| 8306 | .constant_items = .{}, | 8553 | .constant_items = .{}, |
| 8307 | .constant_extra = .{}, | 8554 | .constant_extra = .{}, |
| 8308 | .constant_limbs = .{}, | 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 | if (self.useLibLlvm()) self.llvm = .{ | 8565 | if (self.useLibLlvm()) self.llvm = .{ |
| 8311 | .context = llvm.Context.create(), | 8566 | .context = llvm.Context.create(), |
| ... | @@ -8395,6 +8650,7 @@ pub fn init(options: Options) InitError!Builder { | ... | @@ -8395,6 +8650,7 @@ pub fn init(options: Options) InitError!Builder { |
| 8395 | assert(try self.intConst(.i1, 0) == .false); | 8650 | assert(try self.intConst(.i1, 0) == .false); |
| 8396 | assert(try self.intConst(.i1, 1) == .true); | 8651 | assert(try self.intConst(.i1, 1) == .true); |
| 8397 | assert(try self.noneConst(.token) == .none); | 8652 | assert(try self.noneConst(.token) == .none); |
| | 8653 | assert(try self.debugNone() == .none); |
| 8398 | | 8654 | |
| 8399 | return self; | 8655 | return self; |
| 8400 | } | 8656 | } |
| ... | @@ -8445,6 +8701,14 @@ pub fn deinit(self: *Builder) void { | ... | @@ -8445,6 +8701,14 @@ pub fn deinit(self: *Builder) void { |
| 8445 | self.constant_extra.deinit(self.gpa); | 8701 | self.constant_extra.deinit(self.gpa); |
| 8446 | self.constant_limbs.deinit(self.gpa); | 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 | self.* = undefined; | 8712 | self.* = undefined; |
| 8449 | } | 8713 | } |
| 8450 | | 8714 | |
| ... | @@ -12042,6 +12306,1188 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite | ... | @@ -12042,6 +12306,1188 @@ fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Ite |
| 12042 | return self.constantExtraDataTrail(T, index).data; | 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 | pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]const u32 { | 13491 | pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]const u32 { |
| 12046 | const BitcodeWriter = bitcode_writer.BitcodeWriter(&.{ Type, FunctionAttributes }); | 13492 | const BitcodeWriter = bitcode_writer.BitcodeWriter(&.{ Type, FunctionAttributes }); |
| 12047 | var bitcode = BitcodeWriter.init(allocator, &.{ | 13493 | var bitcode = BitcodeWriter.init(allocator, &.{ |
| ... | @@ -12977,6 +14423,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co | ... | @@ -12977,6 +14423,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 12977 | return @intCast(switch (value.unwrap()) { | 14423 | return @intCast(switch (value.unwrap()) { |
| 12978 | .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(), | 14424 | .instruction => |instruction| instruction.valueIndex(adapter.func) + adapter.firstInstr(), |
| 12979 | .constant => |constant| adapter.constant_adapter.getConstantIndex(constant), | 14425 | .constant => |constant| adapter.constant_adapter.getConstantIndex(constant), |
| | 14426 | .metadata => unreachable, |
| 12980 | }); | 14427 | }); |
| 12981 | } | 14428 | } |
| 12982 | | 14429 | |