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(...@@ -293,6 +293,22 @@ pub fn ArrayHashMap(
293 return self.unmanaged.getPtrAdapted(key, ctx);293 return self.unmanaged.getPtrAdapted(key, ctx);
294 }294 }
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
296 /// Check whether a key is stored in the map312 /// Check whether a key is stored in the map
297 pub fn contains(self: Self, key: K) bool {313 pub fn contains(self: Self, key: K) bool {
298 return self.unmanaged.containsContext(key, self.ctx);314 return self.unmanaged.containsContext(key, self.ctx);
...@@ -967,6 +983,34 @@ pub fn ArrayHashMapUnmanaged(...@@ -967,6 +983,34 @@ pub fn ArrayHashMapUnmanaged(
967 return if (@sizeOf(*V) == 0) @as(*V, undefined) else &self.values()[index];983 return if (@sizeOf(*V) == 0) @as(*V, undefined) else &self.values()[index];
968 }984 }
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
970 /// Check whether a key is stored in the map1014 /// Check whether a key is stored in the map
971 pub fn contains(self: Self, key: K) bool {1015 pub fn contains(self: Self, key: K) bool {
972 if (@sizeOf(Context) != 0)1016 if (@sizeOf(Context) != 0)
lib/std/hash_map.zig+48
...@@ -561,6 +561,21 @@ pub fn HashMap(...@@ -561,6 +561,21 @@ pub fn HashMap(
561 return self.unmanaged.getPtrAdapted(key, ctx);561 return self.unmanaged.getPtrAdapted(key, ctx);
562 }562 }
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
564 /// Finds the key and value associated with a key in the map579 /// Finds the key and value associated with a key in the map
565 pub fn getEntry(self: Self, key: K) ?Entry {580 pub fn getEntry(self: Self, key: K) ?Entry {
566 return self.unmanaged.getEntryContext(key, self.ctx);581 return self.unmanaged.getEntryContext(key, self.ctx);
...@@ -1124,6 +1139,38 @@ pub fn HashMapUnmanaged(...@@ -1124,6 +1139,38 @@ pub fn HashMapUnmanaged(
1124 result.value_ptr.* = value;1139 result.value_ptr.* = value;
1125 }1140 }
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
1127 /// Get an optional pointer to the value associated with key, if present.1174 /// Get an optional pointer to the value associated with key, if present.
1128 pub fn getPtr(self: Self, key: K) ?*V {1175 pub fn getPtr(self: Self, key: K) ?*V {
1129 if (@sizeOf(Context) != 0)1176 if (@sizeOf(Context) != 0)
...@@ -1948,6 +1995,7 @@ test "std.hash_map getOrPutAdapted" {...@@ -1948,6 +1995,7 @@ test "std.hash_map getOrPutAdapted" {
1948 try testing.expect(result.found_existing);1995 try testing.expect(result.found_existing);
1949 try testing.expectEqual(real_keys[i], result.key_ptr.*);1996 try testing.expectEqual(real_keys[i], result.key_ptr.*);
1950 try testing.expectEqual(@as(u64, i) * 2, result.value_ptr.*);1997 try testing.expectEqual(@as(u64, i) * 2, result.value_ptr.*);
1998 try testing.expectEqual(real_keys[i], map.getKeyAdapted(key_str, AdaptedContext{}).?);
1951 }1999 }
1952}2000}
19532001
src/link/MachO.zig+15-11
...@@ -148,7 +148,7 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{},...@@ -148,7 +148,7 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{},
148stub_helper_stubs_start_off: ?u64 = null,148stub_helper_stubs_start_off: ?u64 = null,
149149
150strtab: std.ArrayListUnmanaged(u8) = .{},150strtab: 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
153got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{},153got_entries: std.ArrayListUnmanaged(GotIndirectionKey) = .{},
154got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{},154got_entries_map: std.AutoHashMapUnmanaged(GotIndirectionKey, u32) = .{},
...@@ -938,7 +938,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -938,7 +938,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
938938
939 {939 {
940 // Add dyld_stub_binder as the final GOT entry.940 // 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{
942 .strtab = &self.strtab,942 .strtab = &self.strtab,
943 }) orelse unreachable;943 }) orelse unreachable;
944 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;944 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
...@@ -1966,7 +1966,7 @@ fn writeStubHelperCommon(self: *MachO) !void {...@@ -1966,7 +1966,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
1966 code[9] = 0xff;1966 code[9] = 0xff;
1967 code[10] = 0x25;1967 code[10] = 0x25;
1968 {1968 {
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{
1970 .strtab = &self.strtab,1970 .strtab = &self.strtab,
1971 }) orelse unreachable;1971 }) orelse unreachable;
1972 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;1972 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
...@@ -2017,7 +2017,7 @@ fn writeStubHelperCommon(self: *MachO) !void {...@@ -2017,7 +2017,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
2017 code[10] = 0xbf;2017 code[10] = 0xbf;
2018 code[11] = 0xa9;2018 code[11] = 0xa9;
2019 binder_blk_outer: {2019 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{
2021 .strtab = &self.strtab,2021 .strtab = &self.strtab,
2022 }) orelse unreachable;2022 }) orelse unreachable;
2023 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;2023 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
...@@ -2435,7 +2435,7 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2435,7 +2435,7 @@ fn resolveSymbols(self: *MachO) !void {
2435 }2435 }
24362436
2437 // Fourth pass, handle synthetic symbols and flag any undefined references.2437 // 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{
2439 .strtab = &self.strtab,2439 .strtab = &self.strtab,
2440 })) |n_strx| blk: {2440 })) |n_strx| blk: {
2441 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;2441 const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk;
...@@ -2985,7 +2985,7 @@ fn setEntryPoint(self: *MachO) !void {...@@ -2985,7 +2985,7 @@ fn setEntryPoint(self: *MachO) !void {
2985 // TODO we should respect the -entry flag passed in by the user to set a custom2985 // TODO we should respect the -entry flag passed in by the user to set a custom
2986 // entrypoint. For now, assume default of `_main`.2986 // entrypoint. For now, assume default of `_main`.
2987 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;2987 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{
2989 .strtab = &self.strtab,2989 .strtab = &self.strtab,
2990 }) orelse {2990 }) orelse {
2991 log.err("'_main' export not found", .{});2991 log.err("'_main' export not found", .{});
...@@ -4616,7 +4616,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {...@@ -4616,7 +4616,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
4616 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});4616 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
4617 defer self.base.allocator.free(sym_name);4617 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{
4620 .strtab = &self.strtab,4620 .strtab = &self.strtab,
4621 })) |n_strx| {4621 })) |n_strx| {
4622 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;4622 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
...@@ -5858,7 +5858,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {...@@ -5858,7 +5858,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
5858}5858}
58595859
5860pub fn makeString(self: *MachO, string: []const u8) !u32 {5860pub 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.*;
5862 log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off });5868 log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off });
5863 return off;5869 return off;
5864 }5870 }
...@@ -5871,9 +5877,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 {...@@ -5871,9 +5877,7 @@ pub fn makeString(self: *MachO, string: []const u8) !u32 {
5871 self.strtab.appendSliceAssumeCapacity(string);5877 self.strtab.appendSliceAssumeCapacity(string);
5872 self.strtab.appendAssumeCapacity(0);5878 self.strtab.appendAssumeCapacity(0);
58735879
5874 try self.strtab_dir.putContext(self.base.allocator, new_off, new_off, StringIndexContext{5880 gop.key_ptr.* = new_off;
5875 .strtab = &self.strtab,
5876 });
58775881
5878 return new_off;5882 return new_off;
5879}5883}
src/link/MachO/TextBlock.zig+2-2
...@@ -656,7 +656,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc...@@ -656,7 +656,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
656 parsed_rel.where = .local;656 parsed_rel.where = .local;
657 parsed_rel.where_index = where_index;657 parsed_rel.where_index = where_index;
658 } else {658 } 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{
660 .strtab = &context.macho_file.strtab,660 .strtab = &context.macho_file.strtab,
661 }) orelse unreachable;661 }) orelse unreachable;
662 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;662 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...@@ -717,7 +717,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
717 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;717 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
718 subtractor = where_index;718 subtractor = where_index;
719 } else {719 } 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{
721 .strtab = &context.macho_file.strtab,721 .strtab = &context.macho_file.strtab,
722 }) orelse unreachable;722 }) orelse unreachable;
723 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;723 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;