aboutsummaryrefslogtreecommitdiff
path: root/base/runtime/dynamic_map_internal.odin
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-03-13 15:12:14 +0000
committergingerBill <bill@gingerbill.org>2024-03-13 15:12:14 +0000
commitac10f504e467053861fcf00b86bbb2904ddadafe (patch)
tree72cf17f74157b6a3305a2865fe9269a1d319855b /base/runtime/dynamic_map_internal.odin
parentd6353daf91e8cea613ceca705f482062cc1538eb (diff)
Add infinite loop check and early out in `map_insert_hash_dynamic`
Diffstat (limited to 'base/runtime/dynamic_map_internal.odin')
-rw-r--r--base/runtime/dynamic_map_internal.odin16
1 files changed, 13 insertions, 3 deletions
diff --git a/base/runtime/dynamic_map_internal.odin b/base/runtime/dynamic_map_internal.odin
index 6955f4a1e..5ecf2207f 100644
--- a/base/runtime/dynamic_map_internal.odin
+++ b/base/runtime/dynamic_map_internal.odin
@@ -391,7 +391,8 @@ map_alloc_dynamic :: proc "odin" (info: ^Map_Info, log2_capacity: uintptr, alloc
// arrays to reduce variance. This swapping can only be done with memcpy since
// there is no type information.
//
-// This procedure returns the address of the just inserted value.
+// This procedure returns the address of the just inserted value, and will
+// return 'nil' if there was no room to insert the entry
@(require_results)
map_insert_hash_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, ik: uintptr, iv: uintptr) -> (result: uintptr) {
h := h
@@ -415,6 +416,11 @@ map_insert_hash_dynamic :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^
tv := map_cell_index_dynamic(sv, info.vs, 1)
swap_loop: for {
+ if distance > mask
+ // Failed to find an empty slot and prevent infinite loop
+ return 0
+ }
+
element_hash := hs[pos]
if map_hash_is_empty(element_hash) {
@@ -898,7 +904,9 @@ __dynamic_map_set :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_In
}
result := map_insert_hash_dynamic(m, info, hash, uintptr(key), uintptr(value))
- m.len += 1
+ if result != 0 {
+ m.len += 1
+ }
return rawptr(result)
}
__dynamic_map_set_extra_without_hash :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, key, value: rawptr, loc := #caller_location) -> (prev_key_ptr, value_ptr: rawptr) {
@@ -921,7 +929,9 @@ __dynamic_map_set_extra :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^
}
result := map_insert_hash_dynamic(m, info, hash, uintptr(key), uintptr(value))
- m.len += 1
+ if result != 0 {
+ m.len += 1
+ }
return nil, rawptr(result)
}