| ... | @@ -22,6 +22,8 @@ const Opcode = spec.Opcode; | ... | @@ -22,6 +22,8 @@ const Opcode = spec.Opcode; |
| 22 | const IdResult = spec.IdResult; | 22 | const IdResult = spec.IdResult; |
| 23 | const StorageClass = spec.StorageClass; | 23 | const StorageClass = spec.StorageClass; |
| 24 | | 24 | |
| | 25 | const InternPool = @import("../../InternPool.zig"); |
| | 26 | |
| 25 | const Self = @This(); | 27 | const Self = @This(); |
| 26 | | 28 | |
| 27 | map: std.AutoArrayHashMapUnmanaged(void, void) = .{}, | 29 | map: std.AutoArrayHashMapUnmanaged(void, void) = .{}, |
| ... | @@ -31,6 +33,8 @@ extra: std.ArrayListUnmanaged(u32) = .{}, | ... | @@ -31,6 +33,8 @@ extra: std.ArrayListUnmanaged(u32) = .{}, |
| 31 | string_bytes: std.ArrayListUnmanaged(u8) = .{}, | 33 | string_bytes: std.ArrayListUnmanaged(u8) = .{}, |
| 32 | strings: std.AutoArrayHashMapUnmanaged(void, u32) = .{}, | 34 | strings: std.AutoArrayHashMapUnmanaged(void, u32) = .{}, |
| 33 | | 35 | |
| | 36 | recursive_ptrs: std.AutoHashMapUnmanaged(Ref, void) = .{}, |
| | 37 | |
| 34 | const Item = struct { | 38 | const Item = struct { |
| 35 | tag: Tag, | 39 | tag: Tag, |
| 36 | /// The result-id that this item uses. | 40 | /// The result-id that this item uses. |
| ... | @@ -62,18 +66,21 @@ const Tag = enum { | ... | @@ -62,18 +66,21 @@ const Tag = enum { |
| 62 | /// Function (proto)type | 66 | /// Function (proto)type |
| 63 | /// data is payload to FunctionType | 67 | /// data is payload to FunctionType |
| 64 | type_function, | 68 | type_function, |
| 65 | /// Pointer type in the CrossWorkgroup storage class | 69 | // /// Pointer type in the CrossWorkgroup storage class |
| 66 | /// data is child type | 70 | // /// data is child type |
| 67 | type_ptr_generic, | 71 | // type_ptr_generic, |
| 68 | /// Pointer type in the CrossWorkgroup storage class | 72 | // /// Pointer type in the CrossWorkgroup storage class |
| 69 | /// data is child type | 73 | // /// data is child type |
| 70 | type_ptr_crosswgp, | 74 | // type_ptr_crosswgp, |
| 71 | /// Pointer type in the Function storage class | 75 | // /// Pointer type in the Function storage class |
| 72 | /// data is child type | 76 | // /// data is child type |
| 73 | type_ptr_function, | 77 | // type_ptr_function, |
| 74 | /// Simple pointer type that does not have any decorations. | 78 | /// Simple pointer type that does not have any decorations. |
| 75 | /// data is payload to SimplePointerType | 79 | /// data is payload to SimplePointerType |
| 76 | type_ptr_simple, | 80 | type_ptr_simple, |
| | 81 | /// A forward declaration for a pointer. |
| | 82 | /// data is ForwardPointerType |
| | 83 | type_fwd_ptr, |
| 77 | /// Simple structure type that does not have any decorations. | 84 | /// Simple structure type that does not have any decorations. |
| 78 | /// data is payload to SimpleStructType | 85 | /// data is payload to SimpleStructType |
| 79 | type_struct_simple, | 86 | type_struct_simple, |
| ... | @@ -142,6 +149,12 @@ const Tag = enum { | ... | @@ -142,6 +149,12 @@ const Tag = enum { |
| 142 | const SimplePointerType = struct { | 149 | const SimplePointerType = struct { |
| 143 | storage_class: StorageClass, | 150 | storage_class: StorageClass, |
| 144 | child_type: Ref, | 151 | child_type: Ref, |
| | 152 | fwd: Ref, |
| | 153 | }; |
| | 154 | |
| | 155 | const ForwardPointerType = struct { |
| | 156 | storage_class: StorageClass, |
| | 157 | zig_child_type: InternPool.Index, |
| 145 | }; | 158 | }; |
| 146 | | 159 | |
| 147 | /// Trailing: | 160 | /// Trailing: |
| ... | @@ -163,14 +176,14 @@ const Tag = enum { | ... | @@ -163,14 +176,14 @@ const Tag = enum { |
| 163 | fn encode(value: f64) Float64 { | 176 | fn encode(value: f64) Float64 { |
| 164 | const bits = @as(u64, @bitCast(value)); | 177 | const bits = @as(u64, @bitCast(value)); |
| 165 | return .{ | 178 | return .{ |
| 166 | .low = @as(u32, @truncate(bits)), | 179 | .low = @truncate(bits), |
| 167 | .high = @as(u32, @truncate(bits >> 32)), | 180 | .high = @truncate(bits >> 32), |
| 168 | }; | 181 | }; |
| 169 | } | 182 | } |
| 170 | | 183 | |
| 171 | fn decode(self: Float64) f64 { | 184 | fn decode(self: Float64) f64 { |
| 172 | const bits = @as(u64, self.low) | (@as(u64, self.high) << 32); | 185 | const bits = @as(u64, self.low) | (@as(u64, self.high) << 32); |
| 173 | return @as(f64, @bitCast(bits)); | 186 | return @bitCast(bits); |
| 174 | } | 187 | } |
| 175 | }; | 188 | }; |
| 176 | | 189 | |
| ... | @@ -192,8 +205,8 @@ const Tag = enum { | ... | @@ -192,8 +205,8 @@ const Tag = enum { |
| 192 | fn encode(ty: Ref, value: u64) Int64 { | 205 | fn encode(ty: Ref, value: u64) Int64 { |
| 193 | return .{ | 206 | return .{ |
| 194 | .ty = ty, | 207 | .ty = ty, |
| 195 | .low = @as(u32, @truncate(value)), | 208 | .low = @truncate(value), |
| 196 | .high = @as(u32, @truncate(value >> 32)), | 209 | .high = @truncate(value >> 32), |
| 197 | }; | 210 | }; |
| 198 | } | 211 | } |
| 199 | | 212 | |
| ... | @@ -210,8 +223,8 @@ const Tag = enum { | ... | @@ -210,8 +223,8 @@ const Tag = enum { |
| 210 | fn encode(ty: Ref, value: i64) Int64 { | 223 | fn encode(ty: Ref, value: i64) Int64 { |
| 211 | return .{ | 224 | return .{ |
| 212 | .ty = ty, | 225 | .ty = ty, |
| 213 | .low = @as(u32, @truncate(@as(u64, @bitCast(value)))), | 226 | .low = @truncate(@as(u64, @bitCast(value))), |
| 214 | .high = @as(u32, @truncate(@as(u64, @bitCast(value)) >> 32)), | 227 | .high = @truncate(@as(u64, @bitCast(value)) >> 32), |
| 215 | }; | 228 | }; |
| 216 | } | 229 | } |
| 217 | | 230 | |
| ... | @@ -237,6 +250,7 @@ pub const Key = union(enum) { | ... | @@ -237,6 +250,7 @@ pub const Key = union(enum) { |
| 237 | array_type: ArrayType, | 250 | array_type: ArrayType, |
| 238 | function_type: FunctionType, | 251 | function_type: FunctionType, |
| 239 | ptr_type: PointerType, | 252 | ptr_type: PointerType, |
| | 253 | fwd_ptr_type: ForwardPointerType, |
| 240 | struct_type: StructType, | 254 | struct_type: StructType, |
| 241 | opaque_type: OpaqueType, | 255 | opaque_type: OpaqueType, |
| 242 | | 256 | |
| ... | @@ -273,12 +287,18 @@ pub const Key = union(enum) { | ... | @@ -273,12 +287,18 @@ pub const Key = union(enum) { |
| 273 | pub const PointerType = struct { | 287 | pub const PointerType = struct { |
| 274 | storage_class: StorageClass, | 288 | storage_class: StorageClass, |
| 275 | child_type: Ref, | 289 | child_type: Ref, |
| | 290 | fwd: Ref, |
| 276 | // TODO: Decorations: | 291 | // TODO: Decorations: |
| 277 | // - Alignment | 292 | // - Alignment |
| 278 | // - ArrayStride, | 293 | // - ArrayStride, |
| 279 | // - MaxByteOffset, | 294 | // - MaxByteOffset, |
| 280 | }; | 295 | }; |
| 281 | | 296 | |
| | 297 | pub const ForwardPointerType = struct { |
| | 298 | zig_child_type: InternPool.Index, |
| | 299 | storage_class: StorageClass, |
| | 300 | }; |
| | 301 | |
| 282 | pub const StructType = struct { | 302 | pub const StructType = struct { |
| 283 | // TODO: Decorations. | 303 | // TODO: Decorations. |
| 284 | /// The name of the structure. Can be `.none`. | 304 | /// The name of the structure. Can be `.none`. |
| ... | @@ -313,21 +333,21 @@ pub const Key = union(enum) { | ... | @@ -313,21 +333,21 @@ pub const Key = union(enum) { |
| 313 | /// Turns this value into the corresponding 32-bit literal, 2s complement signed. | 333 | /// Turns this value into the corresponding 32-bit literal, 2s complement signed. |
| 314 | fn toBits32(self: Int) u32 { | 334 | fn toBits32(self: Int) u32 { |
| 315 | return switch (self.value) { | 335 | return switch (self.value) { |
| 316 | .uint64 => |val| @as(u32, @intCast(val)), | 336 | .uint64 => |val| @intCast(val), |
| 317 | .int64 => |val| if (val < 0) @as(u32, @bitCast(@as(i32, @intCast(val)))) else @as(u32, @intCast(val)), | 337 | .int64 => |val| if (val < 0) @bitCast(@as(i32, @intCast(val))) else @intCast(val), |
| 318 | }; | 338 | }; |
| 319 | } | 339 | } |
| 320 | | 340 | |
| 321 | fn toBits64(self: Int) u64 { | 341 | fn toBits64(self: Int) u64 { |
| 322 | return switch (self.value) { | 342 | return switch (self.value) { |
| 323 | .uint64 => |val| val, | 343 | .uint64 => |val| val, |
| 324 | .int64 => |val| @as(u64, @bitCast(val)), | 344 | .int64 => |val| @bitCast(val), |
| 325 | }; | 345 | }; |
| 326 | } | 346 | } |
| 327 | | 347 | |
| 328 | fn to(self: Int, comptime T: type) T { | 348 | fn to(self: Int, comptime T: type) T { |
| 329 | return switch (self.value) { | 349 | return switch (self.value) { |
| 330 | inline else => |val| @as(T, @intCast(val)), | 350 | inline else => |val| @intCast(val), |
| 331 | }; | 351 | }; |
| 332 | } | 352 | } |
| 333 | }; | 353 | }; |
| ... | @@ -387,7 +407,7 @@ pub const Key = union(enum) { | ... | @@ -387,7 +407,7 @@ pub const Key = union(enum) { |
| 387 | }, | 407 | }, |
| 388 | inline else => |key| std.hash.autoHash(&hasher, key), | 408 | inline else => |key| std.hash.autoHash(&hasher, key), |
| 389 | } | 409 | } |
| 390 | return @as(u32, @truncate(hasher.final())); | 410 | return @truncate(hasher.final()); |
| 391 | } | 411 | } |
| 392 | | 412 | |
| 393 | fn eql(a: Key, b: Key) bool { | 413 | fn eql(a: Key, b: Key) bool { |
| ... | @@ -419,7 +439,7 @@ pub const Key = union(enum) { | ... | @@ -419,7 +439,7 @@ pub const Key = union(enum) { |
| 419 | | 439 | |
| 420 | pub fn eql(ctx: @This(), a: Key, b_void: void, b_index: usize) bool { | 440 | pub fn eql(ctx: @This(), a: Key, b_void: void, b_index: usize) bool { |
| 421 | _ = b_void; | 441 | _ = b_void; |
| 422 | return ctx.self.lookup(@as(Ref, @enumFromInt(b_index))).eql(a); | 442 | return ctx.self.lookup(@enumFromInt(b_index)).eql(a); |
| 423 | } | 443 | } |
| 424 | | 444 | |
| 425 | pub fn hash(ctx: @This(), a: Key) u32 { | 445 | pub fn hash(ctx: @This(), a: Key) u32 { |
| ... | @@ -450,6 +470,7 @@ pub fn deinit(self: *Self, spv: *const Module) void { | ... | @@ -450,6 +470,7 @@ pub fn deinit(self: *Self, spv: *const Module) void { |
| 450 | self.extra.deinit(spv.gpa); | 470 | self.extra.deinit(spv.gpa); |
| 451 | self.string_bytes.deinit(spv.gpa); | 471 | self.string_bytes.deinit(spv.gpa); |
| 452 | self.strings.deinit(spv.gpa); | 472 | self.strings.deinit(spv.gpa); |
| | 473 | self.recursive_ptrs.deinit(spv.gpa); |
| 453 | } | 474 | } |
| 454 | | 475 | |
| 455 | /// Actually materialize the database into spir-v instructions. | 476 | /// Actually materialize the database into spir-v instructions. |
| ... | @@ -460,7 +481,7 @@ pub fn materialize(self: *const Self, spv: *Module) !Section { | ... | @@ -460,7 +481,7 @@ pub fn materialize(self: *const Self, spv: *Module) !Section { |
| 460 | var section = Section{}; | 481 | var section = Section{}; |
| 461 | errdefer section.deinit(spv.gpa); | 482 | errdefer section.deinit(spv.gpa); |
| 462 | for (self.items.items(.result_id), 0..) |result_id, index| { | 483 | for (self.items.items(.result_id), 0..) |result_id, index| { |
| 463 | try self.emit(spv, result_id, @as(Ref, @enumFromInt(index)), &section); | 484 | try self.emit(spv, result_id, @enumFromInt(index), &section); |
| 464 | } | 485 | } |
| 465 | return section; | 486 | return section; |
| 466 | } | 487 | } |
| ... | @@ -538,6 +559,15 @@ fn emit( | ... | @@ -538,6 +559,15 @@ fn emit( |
| 538 | }); | 559 | }); |
| 539 | // TODO: Decorations? | 560 | // TODO: Decorations? |
| 540 | }, | 561 | }, |
| | 562 | .fwd_ptr_type => |fwd| { |
| | 563 | // Only emit the OpTypeForwardPointer if its actually required. |
| | 564 | if (self.recursive_ptrs.contains(ref)) { |
| | 565 | try section.emit(spv.gpa, .OpTypeForwardPointer, .{ |
| | 566 | .pointer_type = result_id, |
| | 567 | .storage_class = fwd.storage_class, |
| | 568 | }); |
| | 569 | } |
| | 570 | }, |
| 541 | .struct_type => |struct_type| { | 571 | .struct_type => |struct_type| { |
| 542 | try section.emitRaw(spv.gpa, .OpTypeStruct, 1 + struct_type.member_types.len); | 572 | try section.emitRaw(spv.gpa, .OpTypeStruct, 1 + struct_type.member_types.len); |
| 543 | section.writeOperand(IdResult, result_id); | 573 | section.writeOperand(IdResult, result_id); |
| ... | @@ -549,7 +579,7 @@ fn emit( | ... | @@ -549,7 +579,7 @@ fn emit( |
| 549 | } | 579 | } |
| 550 | for (struct_type.memberNames(), 0..) |member_name, i| { | 580 | for (struct_type.memberNames(), 0..) |member_name, i| { |
| 551 | if (self.getString(member_name)) |name| { | 581 | if (self.getString(member_name)) |name| { |
| 552 | try spv.memberDebugName(result_id, @as(u32, @intCast(i)), name); | 582 | try spv.memberDebugName(result_id, @intCast(i), name); |
| 553 | } | 583 | } |
| 554 | } | 584 | } |
| 555 | // TODO: Decorations? | 585 | // TODO: Decorations? |
| ... | @@ -625,13 +655,12 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { | ... | @@ -625,13 +655,12 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 625 | const adapter: Key.Adapter = .{ .self = self }; | 655 | const adapter: Key.Adapter = .{ .self = self }; |
| 626 | const entry = try self.map.getOrPutAdapted(spv.gpa, key, adapter); | 656 | const entry = try self.map.getOrPutAdapted(spv.gpa, key, adapter); |
| 627 | if (entry.found_existing) { | 657 | if (entry.found_existing) { |
| 628 | return @as(Ref, @enumFromInt(entry.index)); | 658 | return @enumFromInt(entry.index); |
| 629 | } | 659 | } |
| 630 | const result_id = spv.allocId(); | | |
| 631 | const item: Item = switch (key) { | 660 | const item: Item = switch (key) { |
| 632 | inline .void_type, .bool_type => .{ | 661 | inline .void_type, .bool_type => .{ |
| 633 | .tag = .type_simple, | 662 | .tag = .type_simple, |
| 634 | .result_id = result_id, | 663 | .result_id = spv.allocId(), |
| 635 | .data = @intFromEnum(key.toSimpleType()), | 664 | .data = @intFromEnum(key.toSimpleType()), |
| 636 | }, | 665 | }, |
| 637 | .int_type => |int| blk: { | 666 | .int_type => |int| blk: { |
| ... | @@ -641,87 +670,104 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { | ... | @@ -641,87 +670,104 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 641 | }; | 670 | }; |
| 642 | break :blk .{ | 671 | break :blk .{ |
| 643 | .tag = t, | 672 | .tag = t, |
| 644 | .result_id = result_id, | 673 | .result_id = spv.allocId(), |
| 645 | .data = int.bits, | 674 | .data = int.bits, |
| 646 | }; | 675 | }; |
| 647 | }, | 676 | }, |
| 648 | .float_type => |float| .{ | 677 | .float_type => |float| .{ |
| 649 | .tag = .type_float, | 678 | .tag = .type_float, |
| 650 | .result_id = result_id, | 679 | .result_id = spv.allocId(), |
| 651 | .data = float.bits, | 680 | .data = float.bits, |
| 652 | }, | 681 | }, |
| 653 | .vector_type => |vector| .{ | 682 | .vector_type => |vector| .{ |
| 654 | .tag = .type_vector, | 683 | .tag = .type_vector, |
| 655 | .result_id = result_id, | 684 | .result_id = spv.allocId(), |
| 656 | .data = try self.addExtra(spv, vector), | 685 | .data = try self.addExtra(spv, vector), |
| 657 | }, | 686 | }, |
| 658 | .array_type => |array| .{ | 687 | .array_type => |array| .{ |
| 659 | .tag = .type_array, | 688 | .tag = .type_array, |
| 660 | .result_id = result_id, | 689 | .result_id = spv.allocId(), |
| 661 | .data = try self.addExtra(spv, array), | 690 | .data = try self.addExtra(spv, array), |
| 662 | }, | 691 | }, |
| 663 | .function_type => |function| blk: { | 692 | .function_type => |function| blk: { |
| 664 | const extra = try self.addExtra(spv, Tag.FunctionType{ | 693 | const extra = try self.addExtra(spv, Tag.FunctionType{ |
| 665 | .param_len = @as(u32, @intCast(function.parameters.len)), | 694 | .param_len = @intCast(function.parameters.len), |
| 666 | .return_type = function.return_type, | 695 | .return_type = function.return_type, |
| 667 | }); | 696 | }); |
| 668 | try self.extra.appendSlice(spv.gpa, @as([]const u32, @ptrCast(function.parameters))); | 697 | try self.extra.appendSlice(spv.gpa, @ptrCast(function.parameters)); |
| 669 | break :blk .{ | 698 | break :blk .{ |
| 670 | .tag = .type_function, | 699 | .tag = .type_function, |
| 671 | .result_id = result_id, | 700 | .result_id = spv.allocId(), |
| 672 | .data = extra, | 701 | .data = extra, |
| 673 | }; | 702 | }; |
| 674 | }, | 703 | }, |
| 675 | .ptr_type => |ptr| switch (ptr.storage_class) { | 704 | // .ptr_type => |ptr| switch (ptr.storage_class) { |
| 676 | .Generic => Item{ | 705 | // .Generic => Item{ |
| 677 | .tag = .type_ptr_generic, | 706 | // .tag = .type_ptr_generic, |
| 678 | .result_id = result_id, | 707 | // .result_id = spv.allocId(), |
| 679 | .data = @intFromEnum(ptr.child_type), | 708 | // .data = @intFromEnum(ptr.child_type), |
| 680 | }, | 709 | // }, |
| 681 | .CrossWorkgroup => Item{ | 710 | // .CrossWorkgroup => Item{ |
| 682 | .tag = .type_ptr_crosswgp, | 711 | // .tag = .type_ptr_crosswgp, |
| 683 | .result_id = result_id, | 712 | // .result_id = spv.allocId(), |
| 684 | .data = @intFromEnum(ptr.child_type), | 713 | // .data = @intFromEnum(ptr.child_type), |
| 685 | }, | 714 | // }, |
| 686 | .Function => Item{ | 715 | // .Function => Item{ |
| 687 | .tag = .type_ptr_function, | 716 | // .tag = .type_ptr_function, |
| 688 | .result_id = result_id, | 717 | // .result_id = spv.allocId(), |
| 689 | .data = @intFromEnum(ptr.child_type), | 718 | // .data = @intFromEnum(ptr.child_type), |
| 690 | }, | 719 | // }, |
| 691 | else => |storage_class| Item{ | 720 | // else => |storage_class| Item{ |
| 692 | .tag = .type_ptr_simple, | 721 | // .tag = .type_ptr_simple, |
| 693 | .result_id = result_id, | 722 | // .result_id = spv.allocId(), |
| 694 | .data = try self.addExtra(spv, Tag.SimplePointerType{ | 723 | // .data = try self.addExtra(spv, Tag.SimplePointerType{ |
| 695 | .storage_class = storage_class, | 724 | // .storage_class = storage_class, |
| 696 | .child_type = ptr.child_type, | 725 | // .child_type = ptr.child_type, |
| 697 | }), | 726 | // }), |
| 698 | }, | 727 | // }, |
| | 728 | // }, |
| | 729 | .ptr_type => |ptr| Item{ |
| | 730 | .tag = .type_ptr_simple, |
| | 731 | .result_id = self.resultId(ptr.fwd), |
| | 732 | .data = try self.addExtra(spv, Tag.SimplePointerType{ |
| | 733 | .storage_class = ptr.storage_class, |
| | 734 | .child_type = ptr.child_type, |
| | 735 | .fwd = ptr.fwd, |
| | 736 | }), |
| | 737 | }, |
| | 738 | .fwd_ptr_type => |fwd| Item{ |
| | 739 | .tag = .type_fwd_ptr, |
| | 740 | .result_id = spv.allocId(), |
| | 741 | .data = try self.addExtra(spv, Tag.ForwardPointerType{ |
| | 742 | .zig_child_type = fwd.zig_child_type, |
| | 743 | .storage_class = fwd.storage_class, |
| | 744 | }), |
| 699 | }, | 745 | }, |
| 700 | .struct_type => |struct_type| blk: { | 746 | .struct_type => |struct_type| blk: { |
| 701 | const extra = try self.addExtra(spv, Tag.SimpleStructType{ | 747 | const extra = try self.addExtra(spv, Tag.SimpleStructType{ |
| 702 | .name = struct_type.name, | 748 | .name = struct_type.name, |
| 703 | .members_len = @as(u32, @intCast(struct_type.member_types.len)), | 749 | .members_len = @intCast(struct_type.member_types.len), |
| 704 | }); | 750 | }); |
| 705 | try self.extra.appendSlice(spv.gpa, @as([]const u32, @ptrCast(struct_type.member_types))); | 751 | try self.extra.appendSlice(spv.gpa, @ptrCast(struct_type.member_types)); |
| 706 | | 752 | |
| 707 | if (struct_type.member_names) |member_names| { | 753 | if (struct_type.member_names) |member_names| { |
| 708 | try self.extra.appendSlice(spv.gpa, @as([]const u32, @ptrCast(member_names))); | 754 | try self.extra.appendSlice(spv.gpa, @ptrCast(member_names)); |
| 709 | break :blk Item{ | 755 | break :blk Item{ |
| 710 | .tag = .type_struct_simple_with_member_names, | 756 | .tag = .type_struct_simple_with_member_names, |
| 711 | .result_id = result_id, | 757 | .result_id = spv.allocId(), |
| 712 | .data = extra, | 758 | .data = extra, |
| 713 | }; | 759 | }; |
| 714 | } else { | 760 | } else { |
| 715 | break :blk Item{ | 761 | break :blk Item{ |
| 716 | .tag = .type_struct_simple, | 762 | .tag = .type_struct_simple, |
| 717 | .result_id = result_id, | 763 | .result_id = spv.allocId(), |
| 718 | .data = extra, | 764 | .data = extra, |
| 719 | }; | 765 | }; |
| 720 | } | 766 | } |
| 721 | }, | 767 | }, |
| 722 | .opaque_type => |opaque_type| Item{ | 768 | .opaque_type => |opaque_type| Item{ |
| 723 | .tag = .type_opaque, | 769 | .tag = .type_opaque, |
| 724 | .result_id = result_id, | 770 | .result_id = spv.allocId(), |
| 725 | .data = @intFromEnum(opaque_type.name), | 771 | .data = @intFromEnum(opaque_type.name), |
| 726 | }, | 772 | }, |
| 727 | .int => |int| blk: { | 773 | .int => |int| blk: { |
| ... | @@ -729,13 +775,13 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { | ... | @@ -729,13 +775,13 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 729 | if (int_type.signedness == .unsigned and int_type.bits == 8) { | 775 | if (int_type.signedness == .unsigned and int_type.bits == 8) { |
| 730 | break :blk .{ | 776 | break :blk .{ |
| 731 | .tag = .uint8, | 777 | .tag = .uint8, |
| 732 | .result_id = result_id, | 778 | .result_id = spv.allocId(), |
| 733 | .data = int.to(u8), | 779 | .data = int.to(u8), |
| 734 | }; | 780 | }; |
| 735 | } else if (int_type.signedness == .unsigned and int_type.bits == 32) { | 781 | } else if (int_type.signedness == .unsigned and int_type.bits == 32) { |
| 736 | break :blk .{ | 782 | break :blk .{ |
| 737 | .tag = .uint32, | 783 | .tag = .uint32, |
| 738 | .result_id = result_id, | 784 | .result_id = spv.allocId(), |
| 739 | .data = int.to(u32), | 785 | .data = int.to(u32), |
| 740 | }; | 786 | }; |
| 741 | } | 787 | } |
| ... | @@ -745,32 +791,32 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { | ... | @@ -745,32 +791,32 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 745 | if (val >= 0 and val <= std.math.maxInt(u32)) { | 791 | if (val >= 0 and val <= std.math.maxInt(u32)) { |
| 746 | break :blk .{ | 792 | break :blk .{ |
| 747 | .tag = .uint_small, | 793 | .tag = .uint_small, |
| 748 | .result_id = result_id, | 794 | .result_id = spv.allocId(), |
| 749 | .data = try self.addExtra(spv, Tag.UInt32{ | 795 | .data = try self.addExtra(spv, Tag.UInt32{ |
| 750 | .ty = int.ty, | 796 | .ty = int.ty, |
| 751 | .value = @as(u32, @intCast(val)), | 797 | .value = @intCast(val), |
| 752 | }), | 798 | }), |
| 753 | }; | 799 | }; |
| 754 | } else if (val >= std.math.minInt(i32) and val <= std.math.maxInt(i32)) { | 800 | } else if (val >= std.math.minInt(i32) and val <= std.math.maxInt(i32)) { |
| 755 | break :blk .{ | 801 | break :blk .{ |
| 756 | .tag = .int_small, | 802 | .tag = .int_small, |
| 757 | .result_id = result_id, | 803 | .result_id = spv.allocId(), |
| 758 | .data = try self.addExtra(spv, Tag.Int32{ | 804 | .data = try self.addExtra(spv, Tag.Int32{ |
| 759 | .ty = int.ty, | 805 | .ty = int.ty, |
| 760 | .value = @as(i32, @intCast(val)), | 806 | .value = @intCast(val), |
| 761 | }), | 807 | }), |
| 762 | }; | 808 | }; |
| 763 | } else if (val < 0) { | 809 | } else if (val < 0) { |
| 764 | break :blk .{ | 810 | break :blk .{ |
| 765 | .tag = .int_large, | 811 | .tag = .int_large, |
| 766 | .result_id = result_id, | 812 | .result_id = spv.allocId(), |
| 767 | .data = try self.addExtra(spv, Tag.Int64.encode(int.ty, @as(i64, @intCast(val)))), | 813 | .data = try self.addExtra(spv, Tag.Int64.encode(int.ty, @intCast(val))), |
| 768 | }; | 814 | }; |
| 769 | } else { | 815 | } else { |
| 770 | break :blk .{ | 816 | break :blk .{ |
| 771 | .tag = .uint_large, | 817 | .tag = .uint_large, |
| 772 | .result_id = result_id, | 818 | .result_id = spv.allocId(), |
| 773 | .data = try self.addExtra(spv, Tag.UInt64.encode(int.ty, @as(u64, @intCast(val)))), | 819 | .data = try self.addExtra(spv, Tag.UInt64.encode(int.ty, @intCast(val))), |
| 774 | }; | 820 | }; |
| 775 | } | 821 | } |
| 776 | }, | 822 | }, |
| ... | @@ -779,29 +825,29 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { | ... | @@ -779,29 +825,29 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 779 | .float => |float| switch (self.lookup(float.ty).float_type.bits) { | 825 | .float => |float| switch (self.lookup(float.ty).float_type.bits) { |
| 780 | 16 => .{ | 826 | 16 => .{ |
| 781 | .tag = .float16, | 827 | .tag = .float16, |
| 782 | .result_id = result_id, | 828 | .result_id = spv.allocId(), |
| 783 | .data = @as(u16, @bitCast(float.value.float16)), | 829 | .data = @as(u16, @bitCast(float.value.float16)), |
| 784 | }, | 830 | }, |
| 785 | 32 => .{ | 831 | 32 => .{ |
| 786 | .tag = .float32, | 832 | .tag = .float32, |
| 787 | .result_id = result_id, | 833 | .result_id = spv.allocId(), |
| 788 | .data = @as(u32, @bitCast(float.value.float32)), | 834 | .data = @as(u32, @bitCast(float.value.float32)), |
| 789 | }, | 835 | }, |
| 790 | 64 => .{ | 836 | 64 => .{ |
| 791 | .tag = .float64, | 837 | .tag = .float64, |
| 792 | .result_id = result_id, | 838 | .result_id = spv.allocId(), |
| 793 | .data = try self.addExtra(spv, Tag.Float64.encode(float.value.float64)), | 839 | .data = try self.addExtra(spv, Tag.Float64.encode(float.value.float64)), |
| 794 | }, | 840 | }, |
| 795 | else => unreachable, | 841 | else => unreachable, |
| 796 | }, | 842 | }, |
| 797 | .undef => |undef| .{ | 843 | .undef => |undef| .{ |
| 798 | .tag = .undef, | 844 | .tag = .undef, |
| 799 | .result_id = result_id, | 845 | .result_id = spv.allocId(), |
| 800 | .data = @intFromEnum(undef.ty), | 846 | .data = @intFromEnum(undef.ty), |
| 801 | }, | 847 | }, |
| 802 | .null => |null_info| .{ | 848 | .null => |null_info| .{ |
| 803 | .tag = .null, | 849 | .tag = .null, |
| 804 | .result_id = result_id, | 850 | .result_id = spv.allocId(), |
| 805 | .data = @intFromEnum(null_info.ty), | 851 | .data = @intFromEnum(null_info.ty), |
| 806 | }, | 852 | }, |
| 807 | .bool => |bool_info| .{ | 853 | .bool => |bool_info| .{ |
| ... | @@ -809,13 +855,13 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { | ... | @@ -809,13 +855,13 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 809 | true => Tag.bool_true, | 855 | true => Tag.bool_true, |
| 810 | false => Tag.bool_false, | 856 | false => Tag.bool_false, |
| 811 | }, | 857 | }, |
| 812 | .result_id = result_id, | 858 | .result_id = spv.allocId(), |
| 813 | .data = @intFromEnum(bool_info.ty), | 859 | .data = @intFromEnum(bool_info.ty), |
| 814 | }, | 860 | }, |
| 815 | }; | 861 | }; |
| 816 | try self.items.append(spv.gpa, item); | 862 | try self.items.append(spv.gpa, item); |
| 817 | | 863 | |
| 818 | return @as(Ref, @enumFromInt(entry.index)); | 864 | return @enumFromInt(entry.index); |
| 819 | } | 865 | } |
| 820 | | 866 | |
| 821 | /// Turn a Ref back into a Key. | 867 | /// Turn a Ref back into a Key. |
| ... | @@ -830,14 +876,14 @@ pub fn lookup(self: *const Self, ref: Ref) Key { | ... | @@ -830,14 +876,14 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 830 | }, | 876 | }, |
| 831 | .type_int_signed => .{ .int_type = .{ | 877 | .type_int_signed => .{ .int_type = .{ |
| 832 | .signedness = .signed, | 878 | .signedness = .signed, |
| 833 | .bits = @as(u16, @intCast(data)), | 879 | .bits = @intCast(data), |
| 834 | } }, | 880 | } }, |
| 835 | .type_int_unsigned => .{ .int_type = .{ | 881 | .type_int_unsigned => .{ .int_type = .{ |
| 836 | .signedness = .unsigned, | 882 | .signedness = .unsigned, |
| 837 | .bits = @as(u16, @intCast(data)), | 883 | .bits = @intCast(data), |
| 838 | } }, | 884 | } }, |
| 839 | .type_float => .{ .float_type = .{ | 885 | .type_float => .{ .float_type = .{ |
| 840 | .bits = @as(u16, @intCast(data)), | 886 | .bits = @intCast(data), |
| 841 | } }, | 887 | } }, |
| 842 | .type_vector => .{ .vector_type = self.extraData(Tag.VectorType, data) }, | 888 | .type_vector => .{ .vector_type = self.extraData(Tag.VectorType, data) }, |
| 843 | .type_array => .{ .array_type = self.extraData(Tag.ArrayType, data) }, | 889 | .type_array => .{ .array_type = self.extraData(Tag.ArrayType, data) }, |
| ... | @@ -846,40 +892,50 @@ pub fn lookup(self: *const Self, ref: Ref) Key { | ... | @@ -846,40 +892,50 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 846 | return .{ | 892 | return .{ |
| 847 | .function_type = .{ | 893 | .function_type = .{ |
| 848 | .return_type = payload.data.return_type, | 894 | .return_type = payload.data.return_type, |
| 849 | .parameters = @as([]const Ref, @ptrCast(self.extra.items[payload.trail..][0..payload.data.param_len])), | 895 | .parameters = @ptrCast(self.extra.items[payload.trail..][0..payload.data.param_len]), |
| 850 | }, | 896 | }, |
| 851 | }; | 897 | }; |
| 852 | }, | 898 | }, |
| 853 | .type_ptr_generic => .{ | 899 | // .type_ptr_generic => .{ |
| 854 | .ptr_type = .{ | 900 | // .ptr_type = .{ |
| 855 | .storage_class = .Generic, | 901 | // .storage_class = .Generic, |
| 856 | .child_type = @as(Ref, @enumFromInt(data)), | 902 | // .child_type = @enumFromInt(data), |
| 857 | }, | 903 | // }, |
| 858 | }, | 904 | // }, |
| 859 | .type_ptr_crosswgp => .{ | 905 | // .type_ptr_crosswgp => .{ |
| 860 | .ptr_type = .{ | 906 | // .ptr_type = .{ |
| 861 | .storage_class = .CrossWorkgroup, | 907 | // .storage_class = .CrossWorkgroup, |
| 862 | .child_type = @as(Ref, @enumFromInt(data)), | 908 | // .child_type = @enumFromInt(data), |
| 863 | }, | 909 | // }, |
| 864 | }, | 910 | // }, |
| 865 | .type_ptr_function => .{ | 911 | // .type_ptr_function => .{ |
| 866 | .ptr_type = .{ | 912 | // .ptr_type = .{ |
| 867 | .storage_class = .Function, | 913 | // .storage_class = .Function, |
| 868 | .child_type = @as(Ref, @enumFromInt(data)), | 914 | // .child_type = @enumFromInt(data), |
| 869 | }, | 915 | // }, |
| 870 | }, | 916 | // }, |
| 871 | .type_ptr_simple => { | 917 | .type_ptr_simple => { |
| 872 | const payload = self.extraData(Tag.SimplePointerType, data); | 918 | const payload = self.extraData(Tag.SimplePointerType, data); |
| 873 | return .{ | 919 | return .{ |
| 874 | .ptr_type = .{ | 920 | .ptr_type = .{ |
| 875 | .storage_class = payload.storage_class, | 921 | .storage_class = payload.storage_class, |
| 876 | .child_type = payload.child_type, | 922 | .child_type = payload.child_type, |
| | 923 | .fwd = payload.fwd, |
| | 924 | }, |
| | 925 | }; |
| | 926 | }, |
| | 927 | .type_fwd_ptr => { |
| | 928 | const payload = self.extraData(Tag.ForwardPointerType, data); |
| | 929 | return .{ |
| | 930 | .fwd_ptr_type = .{ |
| | 931 | .zig_child_type = payload.zig_child_type, |
| | 932 | .storage_class = payload.storage_class, |
| 877 | }, | 933 | }, |
| 878 | }; | 934 | }; |
| 879 | }, | 935 | }, |
| 880 | .type_struct_simple => { | 936 | .type_struct_simple => { |
| 881 | const payload = self.extraDataTrail(Tag.SimpleStructType, data); | 937 | const payload = self.extraDataTrail(Tag.SimpleStructType, data); |
| 882 | const member_types = @as([]const Ref, @ptrCast(self.extra.items[payload.trail..][0..payload.data.members_len])); | 938 | const member_types: []const Ref = @ptrCast(self.extra.items[payload.trail..][0..payload.data.members_len]); |
| 883 | return .{ | 939 | return .{ |
| 884 | .struct_type = .{ | 940 | .struct_type = .{ |
| 885 | .name = payload.data.name, | 941 | .name = payload.data.name, |
| ... | @@ -891,8 +947,8 @@ pub fn lookup(self: *const Self, ref: Ref) Key { | ... | @@ -891,8 +947,8 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 891 | .type_struct_simple_with_member_names => { | 947 | .type_struct_simple_with_member_names => { |
| 892 | const payload = self.extraDataTrail(Tag.SimpleStructType, data); | 948 | const payload = self.extraDataTrail(Tag.SimpleStructType, data); |
| 893 | const trailing = self.extra.items[payload.trail..]; | 949 | const trailing = self.extra.items[payload.trail..]; |
| 894 | const member_types = @as([]const Ref, @ptrCast(trailing[0..payload.data.members_len])); | 950 | const member_types: []const Ref = @ptrCast(trailing[0..payload.data.members_len]); |
| 895 | const member_names = @as([]const String, @ptrCast(trailing[payload.data.members_len..][0..payload.data.members_len])); | 951 | const member_names: []const String = @ptrCast(trailing[payload.data.members_len..][0..payload.data.members_len]); |
| 896 | return .{ | 952 | return .{ |
| 897 | .struct_type = .{ | 953 | .struct_type = .{ |
| 898 | .name = payload.data.name, | 954 | .name = payload.data.name, |
| ... | @@ -903,16 +959,16 @@ pub fn lookup(self: *const Self, ref: Ref) Key { | ... | @@ -903,16 +959,16 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 903 | }, | 959 | }, |
| 904 | .type_opaque => .{ | 960 | .type_opaque => .{ |
| 905 | .opaque_type = .{ | 961 | .opaque_type = .{ |
| 906 | .name = @as(String, @enumFromInt(data)), | 962 | .name = @enumFromInt(data), |
| 907 | }, | 963 | }, |
| 908 | }, | 964 | }, |
| 909 | .float16 => .{ .float = .{ | 965 | .float16 => .{ .float = .{ |
| 910 | .ty = self.get(.{ .float_type = .{ .bits = 16 } }), | 966 | .ty = self.get(.{ .float_type = .{ .bits = 16 } }), |
| 911 | .value = .{ .float16 = @as(f16, @bitCast(@as(u16, @intCast(data)))) }, | 967 | .value = .{ .float16 = @bitCast(@as(u16, @intCast(data))) }, |
| 912 | } }, | 968 | } }, |
| 913 | .float32 => .{ .float = .{ | 969 | .float32 => .{ .float = .{ |
| 914 | .ty = self.get(.{ .float_type = .{ .bits = 32 } }), | 970 | .ty = self.get(.{ .float_type = .{ .bits = 32 } }), |
| 915 | .value = .{ .float32 = @as(f32, @bitCast(data)) }, | 971 | .value = .{ .float32 = @bitCast(data) }, |
| 916 | } }, | 972 | } }, |
| 917 | .float64 => .{ .float = .{ | 973 | .float64 => .{ .float = .{ |
| 918 | .ty = self.get(.{ .float_type = .{ .bits = 64 } }), | 974 | .ty = self.get(.{ .float_type = .{ .bits = 64 } }), |
| ... | @@ -955,17 +1011,17 @@ pub fn lookup(self: *const Self, ref: Ref) Key { | ... | @@ -955,17 +1011,17 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 955 | } }; | 1011 | } }; |
| 956 | }, | 1012 | }, |
| 957 | .undef => .{ .undef = .{ | 1013 | .undef => .{ .undef = .{ |
| 958 | .ty = @as(Ref, @enumFromInt(data)), | 1014 | .ty = @enumFromInt(data), |
| 959 | } }, | 1015 | } }, |
| 960 | .null => .{ .null = .{ | 1016 | .null => .{ .null = .{ |
| 961 | .ty = @as(Ref, @enumFromInt(data)), | 1017 | .ty = @enumFromInt(data), |
| 962 | } }, | 1018 | } }, |
| 963 | .bool_true => .{ .bool = .{ | 1019 | .bool_true => .{ .bool = .{ |
| 964 | .ty = @as(Ref, @enumFromInt(data)), | 1020 | .ty = @enumFromInt(data), |
| 965 | .value = true, | 1021 | .value = true, |
| 966 | } }, | 1022 | } }, |
| 967 | .bool_false => .{ .bool = .{ | 1023 | .bool_false => .{ .bool = .{ |
| 968 | .ty = @as(Ref, @enumFromInt(data)), | 1024 | .ty = @enumFromInt(data), |
| 969 | .value = false, | 1025 | .value = false, |
| 970 | } }, | 1026 | } }, |
| 971 | }; | 1027 | }; |
| ... | @@ -981,7 +1037,7 @@ pub fn resultId(self: Self, ref: Ref) IdResult { | ... | @@ -981,7 +1037,7 @@ pub fn resultId(self: Self, ref: Ref) IdResult { |
| 981 | fn get(self: *const Self, key: Key) Ref { | 1037 | fn get(self: *const Self, key: Key) Ref { |
| 982 | const adapter: Key.Adapter = .{ .self = self }; | 1038 | const adapter: Key.Adapter = .{ .self = self }; |
| 983 | const index = self.map.getIndexAdapted(key, adapter).?; | 1039 | const index = self.map.getIndexAdapted(key, adapter).?; |
| 984 | return @as(Ref, @enumFromInt(index)); | 1040 | return @enumFromInt(index); |
| 985 | } | 1041 | } |
| 986 | | 1042 | |
| 987 | fn addExtra(self: *Self, spv: *Module, extra: anytype) !u32 { | 1043 | fn addExtra(self: *Self, spv: *Module, extra: anytype) !u32 { |
| ... | @@ -991,15 +1047,16 @@ fn addExtra(self: *Self, spv: *Module, extra: anytype) !u32 { | ... | @@ -991,15 +1047,16 @@ fn addExtra(self: *Self, spv: *Module, extra: anytype) !u32 { |
| 991 | } | 1047 | } |
| 992 | | 1048 | |
| 993 | fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 { | 1049 | fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 { |
| 994 | const payload_offset = @as(u32, @intCast(self.extra.items.len)); | 1050 | const payload_offset: u32 = @intCast(self.extra.items.len); |
| 995 | inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| { | 1051 | inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| { |
| 996 | const field_val = @field(extra, field.name); | 1052 | const field_val = @field(extra, field.name); |
| 997 | const word = switch (field.type) { | 1053 | const word: u32 = switch (field.type) { |
| 998 | u32 => field_val, | 1054 | u32 => field_val, |
| 999 | i32 => @as(u32, @bitCast(field_val)), | 1055 | i32 => @bitCast(field_val), |
| 1000 | Ref => @intFromEnum(field_val), | 1056 | Ref => @intFromEnum(field_val), |
| 1001 | StorageClass => @intFromEnum(field_val), | 1057 | StorageClass => @intFromEnum(field_val), |
| 1002 | String => @intFromEnum(field_val), | 1058 | String => @intFromEnum(field_val), |
| | 1059 | InternPool.Index => @intFromEnum(field_val), |
| 1003 | else => @compileError("Invalid type: " ++ @typeName(field.type)), | 1060 | else => @compileError("Invalid type: " ++ @typeName(field.type)), |
| 1004 | }; | 1061 | }; |
| 1005 | self.extra.appendAssumeCapacity(word); | 1062 | self.extra.appendAssumeCapacity(word); |
| ... | @@ -1018,10 +1075,11 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t | ... | @@ -1018,10 +1075,11 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t |
| 1018 | const word = self.extra.items[offset + i]; | 1075 | const word = self.extra.items[offset + i]; |
| 1019 | @field(result, field.name) = switch (field.type) { | 1076 | @field(result, field.name) = switch (field.type) { |
| 1020 | u32 => word, | 1077 | u32 => word, |
| 1021 | i32 => @as(i32, @bitCast(word)), | 1078 | i32 => @bitCast(word), |
| 1022 | Ref => @as(Ref, @enumFromInt(word)), | 1079 | Ref => @enumFromInt(word), |
| 1023 | StorageClass => @as(StorageClass, @enumFromInt(word)), | 1080 | StorageClass => @enumFromInt(word), |
| 1024 | String => @as(String, @enumFromInt(word)), | 1081 | String => @enumFromInt(word), |
| | 1082 | InternPool.Index => @enumFromInt(word), |
| 1025 | else => @compileError("Invalid type: " ++ @typeName(field.type)), | 1083 | else => @compileError("Invalid type: " ++ @typeName(field.type)), |
| 1026 | }; | 1084 | }; |
| 1027 | } | 1085 | } |
| ... | @@ -1049,7 +1107,7 @@ pub const String = enum(u32) { | ... | @@ -1049,7 +1107,7 @@ pub const String = enum(u32) { |
| 1049 | _ = ctx; | 1107 | _ = ctx; |
| 1050 | var hasher = std.hash.Wyhash.init(0); | 1108 | var hasher = std.hash.Wyhash.init(0); |
| 1051 | hasher.update(a); | 1109 | hasher.update(a); |
| 1052 | return @as(u32, @truncate(hasher.final())); | 1110 | return @truncate(hasher.final()); |
| 1053 | } | 1111 | } |
| 1054 | }; | 1112 | }; |
| 1055 | }; | 1113 | }; |
| ... | @@ -1064,10 +1122,10 @@ pub fn addString(self: *Self, spv: *Module, str: []const u8) !String { | ... | @@ -1064,10 +1122,10 @@ pub fn addString(self: *Self, spv: *Module, str: []const u8) !String { |
| 1064 | try self.string_bytes.ensureUnusedCapacity(spv.gpa, 1 + str.len); | 1122 | try self.string_bytes.ensureUnusedCapacity(spv.gpa, 1 + str.len); |
| 1065 | self.string_bytes.appendSliceAssumeCapacity(str); | 1123 | self.string_bytes.appendSliceAssumeCapacity(str); |
| 1066 | self.string_bytes.appendAssumeCapacity(0); | 1124 | self.string_bytes.appendAssumeCapacity(0); |
| 1067 | entry.value_ptr.* = @as(u32, @intCast(offset)); | 1125 | entry.value_ptr.* = @intCast(offset); |
| 1068 | } | 1126 | } |
| 1069 | | 1127 | |
| 1070 | return @as(String, @enumFromInt(entry.index)); | 1128 | return @enumFromInt(entry.index); |
| 1071 | } | 1129 | } |
| 1072 | | 1130 | |
| 1073 | pub fn getString(self: *const Self, ref: String) ?[]const u8 { | 1131 | pub fn getString(self: *const Self, ref: String) ?[]const u8 { |