diff options
| author | gingerBill <bill@gingerbill.org> | 2024-03-13 15:12:14 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-03-13 15:12:14 +0000 |
| commit | ac10f504e467053861fcf00b86bbb2904ddadafe (patch) | |
| tree | 72cf17f74157b6a3305a2865fe9269a1d319855b /base/runtime/dynamic_map_internal.odin | |
| parent | d6353daf91e8cea613ceca705f482062cc1538eb (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.odin | 16 |
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) } |