authorgravatar for fncontroloption@noreply.codeberg.orgFnControlOption <fncontroloption@noreply.codeberg.org> 2021-08-30 21:32:34-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-08-31 00:32:34-04:00
logb25e58b0acb3153814c96161f5d6bc1fa3316800
treefaa127fa9c94c8805d44dad0192c4d74c81cbae3
parentede47d49eba1a2b03a991b8e33bc5f4ff7e24bb9
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.hash_map: add getKey methods (#9607)


4 files changed, 109 insertions(+), 13 deletions(-)

lib/std/array_hash_map.zig+44
......@@ -293,6 +293,22 @@ pub fn ArrayHashMap(
293293 return self.unmanaged.getPtrAdapted(key, ctx);
294294 }
295295
296 /// Find the actual key associated with an adapted key
297 pub fn getKey(self: Self, key: K) ?K {
298 return self.unmanaged.getKeyContext(key, self.ctx);
299 }
300 pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
301 return self.unmanaged.getKeyAdapted(key, ctx);
302 }
303
304 /// Find a pointer to the actual key associated with an adapted key
305 pub fn getKeyPtr(self: Self, key: K) ?*K {
306 return self.unmanaged.getKeyPtrContext(key, self.ctx);
307 }
308 pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
309 return self.unmanaged.getKeyPtrAdapted(key, ctx);
310 }
311
296312 /// Check whether a key is stored in the map
297313 pub fn contains(self: Self, key: K) bool {
298314 return self.unmanaged.containsContext(key, self.ctx);
......@@ -967,6 +983,34 @@ pub fn ArrayHashMapUnmanaged(
967983 return if (@sizeOf(*V) == 0) @as(*V, undefined) else &self.values()[index];
968984 }
969985
986 /// Find the actual key associated with an adapted key
987 pub fn getKey(self: Self, key: K) ?K {
988 if (@sizeOf(Context) != 0)
989 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyContext instead.");
990 return self.getKeyContext(key, undefined);
991 }
992 pub fn getKeyContext(self: Self, key: K, ctx: Context) ?K {
993 return self.getKeyAdapted(key, ctx);
994 }
995 pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
996 const index = self.getIndexAdapted(key, ctx) orelse return null;
997 return self.keys()[index];
998 }
999
1000 /// Find a pointer to the actual key associated with an adapted key
1001 pub fn getKeyPtr(self: Self, key: K) ?*K {
1002 if (@sizeOf(Context) != 0)
1003 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyPtrContext instead.");
1004 return self.getKeyPtrContext(key, undefined);
1005 }
1006 pub fn getKeyPtrContext(self: Self, key: K, ctx: Context) ?*K {
1007 return self.getKeyPtrAdapted(key, ctx);
1008 }
1009 pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
1010 const index = self.getIndexAdapted(key, ctx) orelse return null;
1011 return &self.keys()[index];
1012 }
1013
9701014 /// Check whether a key is stored in the map
9711015 pub fn contains(self: Self, key: K) bool {
9721016 if (@sizeOf(Context) != 0)
lib/std/hash_map.zig+48
......@@ -561,6 +561,21 @@ pub fn HashMap(
561561 return self.unmanaged.getPtrAdapted(key, ctx);
562562 }
563563
564 /// Finds the actual key associated with an adapted key in the map
565 pub fn getKey(self: Self, key: K) ?K {
566 return self.unmanaged.getKeyContext(key, self.ctx);
567 }
568 pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
569 return self.unmanaged.getKeyAdapted(key, ctx);
570 }
571
572 pub fn getKeyPtr(self: Self, key: K) ?*K {
573 return self.unmanaged.getKeyPtrContext(key, self.ctx);
574 }
575 pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
576 return self.unmanaged.getKeyPtrAdapted(key, ctx);
577 }
578
564579 /// Finds the key and value associated with a key in the map
565580 pub fn getEntry(self: Self, key: K) ?Entry {
566581 return self.unmanaged.getEntryContext(key, self.ctx);
......@@ -1124,6 +1139,38 @@ pub fn HashMapUnmanaged(
11241139 result.value_ptr.* = value;
11251140 }
11261141
1142 /// Get an optional pointer to the actual key associated with adapted key, if present.
1143 pub fn getKeyPtr(self: Self, key: K) ?*K {
1144 if (@sizeOf(Context) != 0)
1145 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyPtrContext instead.");
1146 return self.getKeyPtrContext(key, undefined);
1147 }
1148 pub fn getKeyPtrContext(self: Self, key: K, ctx: Context) ?*K {
1149 return self.getKeyPtrAdapted(key, ctx);
1150 }
1151 pub fn getKeyPtrAdapted(self: Self, key: anytype, ctx: anytype) ?*K {
1152 if (self.getIndex(key, ctx)) |idx| {
1153 return &self.keys()[idx];
1154 }
1155 return null;
1156 }
1157
1158 /// Get a copy of the actual key associated with adapted key, if present.
1159 pub fn getKey(self: Self, key: K) ?K {
1160 if (@sizeOf(Context) != 0)
1161 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getKeyContext instead.");
1162 return self.getKeyContext(key, undefined);
1163 }
1164 pub fn getKeyContext(self: Self, key: K, ctx: Context) ?K {
1165 return self.getKeyAdapted(key, ctx);
1166 }
1167 pub fn getKeyAdapted(self: Self, key: anytype, ctx: anytype) ?K {
1168 if (self.getIndex(key, ctx)) |idx| {
1169 return self.keys()[idx];
1170 }
1171 return null;
1172 }
1173
11271174 /// Get an optional pointer to the value associated with key, if present.
11281175 pub fn getPtr(self: Self, key: K) ?*V {
11291176 if (@sizeOf(Context) != 0)
......@@ -1948,6 +1995,7 @@ test "std.hash_map getOrPutAdapted" {
19481995 try testing.expect(result.found_existing);
19491996 try testing.expectEqual(real_keys[i], result.key_ptr.*);
19501997 try testing.expectEqual(@as(u64, i) * 2, result.value_ptr.*);
1998 try testing.expectEqual(real_keys[i], map.getKeyAdapted(key_str, AdaptedContext{}).?);
19511999 }
19522000}
19532001
src/link/MachO.zig+15-11
......@@ -148,7 +148,7 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{},
148148stub_helper_stubs_start_off: ?u64 = null,
149149
150150strtab: std.ArrayListUnmanaged(u8) = .{},
151strtab_dir: std.HashMapUnmanaged(u32, u32, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
151strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{},
152152
153153got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{},
154154got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{},
......@@ -938,7 +938,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
938938
939939 {
940940 // Add dyld_stub_binder as the final GOT entry.
941 const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
941 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
942942 .strtab = &self.strtab,
943943 }) orelse unreachable;
944944 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
......@@ -1966,7 +1966,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
19661966 code[9] = 0xff;
19671967 code[10] = 0x25;
19681968 {
1969 const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
1969 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
19701970 .strtab = &self.strtab,
19711971 }) orelse unreachable;
19721972 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
......@@ -2017,7 +2017,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
20172017 code[10] = 0xbf;
20182018 code[11] = 0xa9;
20192019 binder_blk_outer: {
2020 const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
2020 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
20212021 .strtab = &self.strtab,
20222022 }) orelse unreachable;
20232023 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
......@@ -2435,7 +2435,7 @@ fn resolveSymbols(self: *MachO) !void {
24352435 }
24362436
24372437 // Fourth pass, handle synthetic symbols and flag any undefined references.
2438 if (self.strtab_dir.getAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{
2438 if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{
24392439 .strtab = &self.strtab,
24402440 })) |n_strx| blk: {
24412441 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
......@@ -2985,7 +2985,7 @@ fn setEntryPoint(self: *MachO) !void {
29852985 // TODO we should respect the -entry flag passed in by the user to set a custom
29862986 // entrypoint. For now, assume default of `_main`.
29872987 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
2988 const n_strx = self.strtab_dir.getAdapted(@as([]const u8, "_main"), StringSliceAdapter{
2988 const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{
29892989 .strtab = &self.strtab,
29902990 }) orelse {
29912991 log.err("'_main' export not found", .{});
......@@ -4616,7 +4616,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
46164616 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
46174617 defer self.base.allocator.free(sym_name);
46184618
4619 if (self.strtab_dir.getAdapted(@as([]const u8, sym_name), StringSliceAdapter{
4619 if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{
46204620 .strtab = &self.strtab,
46214621 })) |n_strx| {
46224622 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
......@@ -5858,7 +5858,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
58585858}
58595859
58605860pub fn makeString(self: *MachO, string: []const u8) !u32 {
5861 if (self.strtab_dir.getAdapted(@as([]const u8, string), StringSliceAdapter{ .strtab = &self.strtab })) |off| {
5861 const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{
5862 .strtab = &self.strtab,
5863 }, StringIndexContext{
5864 .strtab = &self.strtab,
5865 });
5866 if (gop.found_existing) {
5867 const off = gop.key_ptr.*;
58625868 log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off });
58635869 return off;
58645870 }
......@@ -5871,9 +5877,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 {
58715877 self.strtab.appendSliceAssumeCapacity(string);
58725878 self.strtab.appendAssumeCapacity(0);
58735879
5874 try self.strtab_dir.putContext(self.base.allocator, new_off, new_off, StringIndexContext{
5875 .strtab = &self.strtab,
5876 });
5880 gop.key_ptr.* = new_off;
58775881
58785882 return new_off;
58795883}
src/link/MachO/TextBlock.zig+2-2
......@@ -656,7 +656,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
656656 parsed_rel.where = .local;
657657 parsed_rel.where_index = where_index;
658658 } else {
659 const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
659 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
660660 .strtab = &context.macho_file.strtab,
661661 }) orelse unreachable;
662662 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
......@@ -717,7 +717,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
717717 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
718718 subtractor = where_index;
719719 } else {
720 const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
720 const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
721721 .strtab = &context.macho_file.strtab,
722722 }) orelse unreachable;
723723 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;