@salang/sa 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/bin/sa.js +19 -1
  2. package/package.json +8 -7
  3. package/sa_std/alloc/layout.sal +12 -0
  4. package/sa_std/alloc/prelude.sa +1 -0
  5. package/sa_std/alloc/prelude.sal +1 -0
  6. package/sa_std/alloc/string.sa +3 -0
  7. package/sa_std/alloc/vec.sa +684 -0
  8. package/sa_std/alloc/vec.sal +4 -0
  9. package/sa_std/any.sa +130 -0
  10. package/sa_std/any.sal +23 -0
  11. package/sa_std/array.sa +1876 -0
  12. package/sa_std/ascii.sa +2 -0
  13. package/sa_std/ascii.sal +1 -0
  14. package/sa_std/async.sla +116 -0
  15. package/sa_std/binary_heap.sa +3003 -0
  16. package/sa_std/binary_heap.sal +7 -0
  17. package/sa_std/borrow.sa +171 -0
  18. package/sa_std/borrow.sal +13 -0
  19. package/sa_std/btree_map.sa +2210 -0
  20. package/sa_std/btree_map.sal +11 -0
  21. package/sa_std/btree_set.sa +1072 -0
  22. package/sa_std/btree_set.sal +6 -0
  23. package/sa_std/char.sa +1309 -0
  24. package/sa_std/char.sal +50 -0
  25. package/sa_std/cmp.sa +554 -0
  26. package/sa_std/cmp.sal +14 -0
  27. package/sa_std/collections/binary_heap.sa +1 -0
  28. package/sa_std/collections/btree_map.sa +1 -0
  29. package/sa_std/collections/btree_set.sa +1 -0
  30. package/sa_std/collections/hashmap.sa +1 -0
  31. package/sa_std/collections/hashset.sa +1 -0
  32. package/sa_std/collections/linked_list.sa +1120 -0
  33. package/sa_std/collections/linked_list.sal +10 -0
  34. package/sa_std/collections/prelude.sa +7 -0
  35. package/sa_std/collections/prelude.sal +1 -0
  36. package/sa_std/collections/vec_deque.sa +1 -0
  37. package/sa_std/collections.sal +13 -0
  38. package/sa_std/convert.sa +1115 -0
  39. package/sa_std/convert.sal +24 -0
  40. package/sa_std/core/arc.sa +233 -0
  41. package/sa_std/core/arc.sal +4 -0
  42. package/sa_std/core/ascii.sa +784 -0
  43. package/sa_std/core/ascii.sal +34 -0
  44. package/sa_std/core/bit.sa +41 -0
  45. package/sa_std/core/box.sa +1 -0
  46. package/sa_std/core/box.sal +2 -0
  47. package/sa_std/core/cell.sa +108 -0
  48. package/sa_std/core/cell.sal +5 -0
  49. package/sa_std/core/cleanup.sa +26 -0
  50. package/sa_std/core/control.sa +20 -0
  51. package/sa_std/core/derive.sa +60 -0
  52. package/sa_std/core/derive.sal +1 -0
  53. package/sa_std/core/dispatch.sa +7 -0
  54. package/sa_std/core/dispatch.sal +5 -0
  55. package/sa_std/core/future.sa +777 -0
  56. package/sa_std/core/future.sal +73 -0
  57. package/sa_std/core/hash.sa +48 -0
  58. package/sa_std/core/iter.sa +2805 -0
  59. package/sa_std/core/iter.sal +4 -0
  60. package/sa_std/core/loop.sa +60 -0
  61. package/sa_std/core/mem.sa +220 -0
  62. package/sa_std/core/option.sa +825 -0
  63. package/sa_std/core/option.sal +11 -0
  64. package/sa_std/core/panic.sa +23 -0
  65. package/sa_std/core/panic.sal +12 -0
  66. package/sa_std/core/prelude.sa +18 -0
  67. package/sa_std/core/prelude.sal +18 -0
  68. package/sa_std/core/rc.sa +225 -0
  69. package/sa_std/core/rc.sal +4 -0
  70. package/sa_std/core/refcell.sa +283 -0
  71. package/sa_std/core/refcell.sal +13 -0
  72. package/sa_std/core/result.sa +708 -0
  73. package/sa_std/core/result.sal +6 -0
  74. package/sa_std/core/rust_patterns.sal +295 -0
  75. package/sa_std/core/sa_core.sa +84 -0
  76. package/sa_std/core/slice.sa +4021 -0
  77. package/sa_std/core/slice.sal +7 -0
  78. package/sa_std/core/task.sa +112 -0
  79. package/sa_std/core/task.sal +15 -0
  80. package/sa_std/core/trait_object.sa +26 -0
  81. package/sa_std/core/trait_object.sal +4 -0
  82. package/sa_std/core/waker.sa +289 -0
  83. package/sa_std/core/waker.sal +31 -0
  84. package/sa_std/core/weak.sa +2 -0
  85. package/sa_std/core/weak.sal +4 -0
  86. package/sa_std/cow.sa +3 -0
  87. package/sa_std/cow.sal +2 -0
  88. package/sa_std/cstring.sa +3 -0
  89. package/sa_std/cstring.sal +2 -0
  90. package/sa_std/default.sa +99 -0
  91. package/sa_std/duration.sa +3 -0
  92. package/sa_std/duration.sal +2 -0
  93. package/sa_std/encoding/json.sa +259 -0
  94. package/sa_std/encoding/json.sai +54 -0
  95. package/sa_std/encoding/json.sal +35 -0
  96. package/sa_std/encoding/prelude.sa +1 -0
  97. package/sa_std/encoding/prelude.sal +0 -0
  98. package/sa_std/env.sa +390 -0
  99. package/sa_std/env.sai +25 -0
  100. package/sa_std/error.sa +253 -0
  101. package/sa_std/error.sal +44 -0
  102. package/sa_std/ffi/cstring.sa +3 -0
  103. package/sa_std/ffi/cstring.sal +1 -0
  104. package/sa_std/ffi/prelude.sa +2 -0
  105. package/sa_std/ffi/prelude.sal +2 -0
  106. package/sa_std/ffi.sa +635 -0
  107. package/sa_std/ffi.sal +51 -0
  108. package/sa_std/fmt.sa +2 -0
  109. package/sa_std/fmt.sai +18 -0
  110. package/sa_std/fmt.sal +35 -0
  111. package/sa_std/fs.sa +1023 -0
  112. package/sa_std/fs.sai +127 -0
  113. package/sa_std/fs.sal +51 -0
  114. package/sa_std/future.sa +2 -0
  115. package/sa_std/future.sal +1 -0
  116. package/sa_std/hash.sa +1486 -0
  117. package/sa_std/hash.sal +13 -0
  118. package/sa_std/hashmap.sa +1962 -0
  119. package/sa_std/hashmap.sal +20 -0
  120. package/sa_std/hashset.sa +1004 -0
  121. package/sa_std/hashset.sal +18 -0
  122. package/sa_std/http2.sa +78 -0
  123. package/sa_std/http2.sai +26 -0
  124. package/sa_std/http2.sal +36 -0
  125. package/sa_std/instant.sa +3 -0
  126. package/sa_std/instant.sal +2 -0
  127. package/sa_std/io/buf_reader.sa +43 -0
  128. package/sa_std/io/buf_writer.sa +35 -0
  129. package/sa_std/io/bufio.sa +4 -0
  130. package/sa_std/io/bufio.sal +4 -0
  131. package/sa_std/io/prelude.sa +1 -0
  132. package/sa_std/io/prelude.sal +1 -0
  133. package/sa_std/io/print.sa +2 -0
  134. package/sa_std/io/print.sai +3 -0
  135. package/sa_std/io.sa +925 -0
  136. package/sa_std/io.sai +25 -0
  137. package/sa_std/io.sal +84 -0
  138. package/sa_std/iter.sa +2 -0
  139. package/sa_std/iter.sal +1 -0
  140. package/sa_std/join_handle.sa +3 -0
  141. package/sa_std/join_handle.sal +2 -0
  142. package/sa_std/libsa_async.sa +80 -0
  143. package/sa_std/m_async.sa +137 -0
  144. package/sa_std/m_async.sal +30 -0
  145. package/sa_std/m_async.sla +2 -0
  146. package/sa_std/manually_drop.sa +3 -0
  147. package/sa_std/manually_drop.sal +2 -0
  148. package/sa_std/marker/phantom_data.sa +3 -0
  149. package/sa_std/marker/phantom_data.sal +1 -0
  150. package/sa_std/marker/prelude.sa +4 -0
  151. package/sa_std/marker/prelude.sal +4 -0
  152. package/sa_std/marker.sa +220 -0
  153. package/sa_std/marker.sal +15 -0
  154. package/sa_std/math.sa +84 -0
  155. package/sa_std/math.sai +10 -0
  156. package/sa_std/mem/manually_drop.sa +3 -0
  157. package/sa_std/mem/manually_drop.sal +1 -0
  158. package/sa_std/mem/prelude.sa +2 -0
  159. package/sa_std/mem/prelude.sal +2 -0
  160. package/sa_std/mem.sa +564 -0
  161. package/sa_std/mem.sal +40 -0
  162. package/sa_std/modstate.sai +19 -0
  163. package/sa_std/net.sa +4227 -0
  164. package/sa_std/net.sai +239 -0
  165. package/sa_std/net.sal +159 -0
  166. package/sa_std/netx.sa +85 -0
  167. package/sa_std/netx.sai +11 -0
  168. package/sa_std/netx.sal +39 -0
  169. package/sa_std/nonzero.sa +3 -0
  170. package/sa_std/nonzero.sal +2 -0
  171. package/sa_std/num/nonzero.sa +3 -0
  172. package/sa_std/num/nonzero.sal +1 -0
  173. package/sa_std/num/prelude.sa +3 -0
  174. package/sa_std/num/prelude.sal +3 -0
  175. package/sa_std/num.sa +17302 -0
  176. package/sa_std/num.sai +11 -0
  177. package/sa_std/num.sal +341 -0
  178. package/sa_std/ops.sa +1884 -0
  179. package/sa_std/ops.sal +68 -0
  180. package/sa_std/option.sa +2 -0
  181. package/sa_std/option.sal +1 -0
  182. package/sa_std/os/fd.sa +96 -0
  183. package/sa_std/os/fd.sai +7 -0
  184. package/sa_std/os/fd.sal +11 -0
  185. package/sa_std/os/prelude.sa +2 -0
  186. package/sa_std/os/prelude.sal +1 -0
  187. package/sa_std/os/unix_ffi.sa +271 -0
  188. package/sa_std/panic.sa +1 -0
  189. package/sa_std/panic.sal +1 -0
  190. package/sa_std/path.sa +3170 -0
  191. package/sa_std/path.sal +12 -0
  192. package/sa_std/phantom_data.sa +3 -0
  193. package/sa_std/phantom_data.sal +2 -0
  194. package/sa_std/pin.sa +79 -0
  195. package/sa_std/pin.sal +5 -0
  196. package/sa_std/plugin_async.sa +90 -0
  197. package/sa_std/plugin_async.sal +29 -0
  198. package/sa_std/plugin_async.sla +4 -0
  199. package/sa_std/plugin_http_async.sa +46 -0
  200. package/sa_std/plugin_http_server.sa +61 -0
  201. package/sa_std/plugin_http_server.sla +2 -0
  202. package/sa_std/plugin_sqlite.sa +106 -0
  203. package/sa_std/plugin_sqlite.sla +2 -0
  204. package/sa_std/prelude.sa +60 -0
  205. package/sa_std/prelude.sal +55 -0
  206. package/sa_std/process.sa +916 -0
  207. package/sa_std/process.sai +57 -0
  208. package/sa_std/process.sal +27 -0
  209. package/sa_std/ptr.sa +503 -0
  210. package/sa_std/ptr.sal +2 -0
  211. package/sa_std/result.sa +2 -0
  212. package/sa_std/result.sal +1 -0
  213. package/sa_std/rust_core.sa +51 -0
  214. package/sa_std/rust_core.sal +26 -0
  215. package/sa_std/sa.mod +7 -0
  216. package/sa_std/sort.sa +156 -0
  217. package/sa_std/str.sla +13 -0
  218. package/sa_std/string.sa +12240 -0
  219. package/sa_std/string.sai +25 -0
  220. package/sa_std/string.sal +17 -0
  221. package/sa_std/string_format.sa +269 -0
  222. package/sa_std/sync/atomic.sa +1500 -0
  223. package/sa_std/sync/atomic.sal +45 -0
  224. package/sa_std/sync/barrier.sa +105 -0
  225. package/sa_std/sync/barrier.sal +7 -0
  226. package/sa_std/sync/condvar.sa +240 -0
  227. package/sa_std/sync/condvar.sal +4 -0
  228. package/sa_std/sync/mpsc.sa +758 -0
  229. package/sa_std/sync/mpsc.sal +42 -0
  230. package/sa_std/sync/mpsc_list.sa +255 -0
  231. package/sa_std/sync/mpsc_list.sal +3 -0
  232. package/sa_std/sync/mutex.sa +182 -0
  233. package/sa_std/sync/mutex.sal +7 -0
  234. package/sa_std/sync/once.sa +371 -0
  235. package/sa_std/sync/once.sal +31 -0
  236. package/sa_std/sync/poison.sa +36 -0
  237. package/sa_std/sync/poison.sal +11 -0
  238. package/sa_std/sync/prelude.sa +8 -0
  239. package/sa_std/sync/prelude.sal +7 -0
  240. package/sa_std/sync/rwlock.sa +369 -0
  241. package/sa_std/sync/rwlock.sal +13 -0
  242. package/sa_std/task.sa +2 -0
  243. package/sa_std/task.sal +1 -0
  244. package/sa_std/term.sa +2 -0
  245. package/sa_std/term.sai +10 -0
  246. package/sa_std/term.sal +33 -0
  247. package/sa_std/testing/assert.sai +4 -0
  248. package/sa_std/testing/mock_io.sa +174 -0
  249. package/sa_std/testing/mock_io.sal +5 -0
  250. package/sa_std/testing/prelude.sa +2 -0
  251. package/sa_std/testing/prelude.sal +1 -0
  252. package/sa_std/text/prelude.sa +1 -0
  253. package/sa_std/text/prelude.sal +1 -0
  254. package/sa_std/text/regex.sa +2 -0
  255. package/sa_std/text/regex.sai +9 -0
  256. package/sa_std/text/regex.sal +33 -0
  257. package/sa_std/thread/join_handle.sa +3 -0
  258. package/sa_std/thread/join_handle.sal +1 -0
  259. package/sa_std/thread/prelude.sa +4 -0
  260. package/sa_std/thread/prelude.sal +3 -0
  261. package/sa_std/thread.sa +160 -0
  262. package/sa_std/thread.sai +11 -0
  263. package/sa_std/thread.sal +4 -0
  264. package/sa_std/thread_local.sa +45 -0
  265. package/sa_std/thread_local.sai +9 -0
  266. package/sa_std/time/duration.sa +3 -0
  267. package/sa_std/time/duration.sal +1 -0
  268. package/sa_std/time/instant.sa +3 -0
  269. package/sa_std/time/instant.sal +1 -0
  270. package/sa_std/time/prelude.sa +4 -0
  271. package/sa_std/time/prelude.sal +4 -0
  272. package/sa_std/time.sa +850 -0
  273. package/sa_std/time.sai +37 -0
  274. package/sa_std/time.sal +35 -0
  275. package/sa_std/time.sla +67 -0
  276. package/sa_std/tls_client.sai +39 -0
  277. package/sa_std/vec.sa +5754 -0
  278. package/sa_std/vec.sal +1 -0
  279. package/sa_std/vec_deque.sa +4925 -0
  280. package/sa_std/vec_deque.sal +8 -0
  281. package/sa_std/vec_runtime_macros.sa +11 -0
  282. package/sa_std/ws_client.sai +57 -0
@@ -0,0 +1,1962 @@
1
+ @import "core/mem.sa"
2
+ @import "core/slice.sal"
3
+ @import "alloc/vec.sa"
4
+ @import "alloc/vec.sal"
5
+ @import "vec.sa"
6
+ @import "num.sa"
7
+ @import "hashmap.sal"
8
+
9
+ @map_hash_ptr(&key: ptr) -> u64:
10
+ L_ENTRY:
11
+ hash = call @map_hash_ptr_seed(&key, 0)
12
+ !key
13
+ return hash
14
+
15
+ @map_hash_ptr_seed(&key: ptr, seed: u64) -> u64:
16
+ L_ENTRY:
17
+ key_bits = bitcast key as u64
18
+ bits0 = xor key_bits, seed
19
+ shift1 = 32 as u64
20
+ shift2 = 16 as u64
21
+ shift3 = 8 as u64
22
+
23
+ bits1 = shr bits0, shift1
24
+ hash1 = xor bits0, bits1
25
+ bits2 = shr hash1, shift2
26
+ hash2 = xor hash1, bits2
27
+ bits3 = shr hash2, shift3
28
+ hash3 = xor hash2, bits3
29
+
30
+ !shift3
31
+ !shift2
32
+ !shift1
33
+ !bits3
34
+ !bits2
35
+ !bits1
36
+ !bits0
37
+ !key_bits
38
+ !hash2
39
+ !hash1
40
+ !seed
41
+ !key
42
+ return hash3
43
+
44
+ @map_table_probe(&slots: ptr, cap: u64, hash: u64, &key: ptr, &out_index: ptr, &out_found: ptr) -> void:
45
+ L_ENTRY:
46
+ index_slot = stack_alloc 8
47
+ remaining_slot = stack_alloc 8
48
+ store out_found+0, 0 as u64
49
+ store out_index+0, 0 as u64
50
+ cap_is_zero = eq cap, 0
51
+ br cap_is_zero -> L_PROBE_END, L_PROBE_INIT
52
+
53
+ L_PROBE_INIT:
54
+ cap_minus_one = sub cap, 1
55
+ start_index = and hash, cap_minus_one
56
+ store index_slot+0, start_index as u64
57
+ store remaining_slot+0, cap as u64
58
+ !start_index
59
+ !cap_minus_one
60
+ jmp L_PROBE_LOOP
61
+
62
+ L_PROBE_LOOP:
63
+ remaining = load remaining_slot+0 as u64
64
+ exhausted = eq remaining, 0
65
+ br exhausted -> L_PROBE_EXHAUSTED, L_PROBE_BODY
66
+
67
+ L_PROBE_BODY:
68
+ !exhausted
69
+ index = load index_slot+0 as u64
70
+ slot_off = mul index, HashMapSlot_SIZE
71
+ slot = ptr_add slots, slot_off
72
+ state = load slot+HashMapSlot_state as u8
73
+ is_empty = eq state, HashMap_STATE_EMPTY
74
+ br is_empty -> L_PROBE_EMPTY, L_PROBE_NONEMPTY
75
+
76
+ L_PROBE_NONEMPTY:
77
+ slot_hash = load slot+HashMapSlot_hash as u64
78
+ hash_match = eq slot_hash, hash
79
+ br hash_match -> L_PROBE_KEY_CHECK, L_PROBE_STEP
80
+
81
+ L_PROBE_STEP:
82
+ next_index = add index, 1
83
+ wrapped = eq next_index, cap
84
+ next_remaining = sub remaining, 1
85
+ store remaining_slot+0, next_remaining as u64
86
+ !next_remaining
87
+ !slot_hash
88
+ !hash_match
89
+ !is_empty
90
+ !state
91
+ !slot
92
+ !slot_off
93
+ !index
94
+ !remaining
95
+ br wrapped -> L_PROBE_WRAP, L_PROBE_CONT
96
+
97
+ L_PROBE_WRAP:
98
+ store index_slot+0, 0 as u64
99
+ !next_index
100
+ !wrapped
101
+ jmp L_PROBE_LOOP
102
+
103
+ L_PROBE_CONT:
104
+ store index_slot+0, next_index as u64
105
+ !next_index
106
+ !wrapped
107
+ jmp L_PROBE_LOOP
108
+
109
+ L_PROBE_KEY_CHECK:
110
+ slot_key = load slot+HashMapSlot_key as ptr
111
+ key_match = eq slot_key, key
112
+ br key_match -> L_PROBE_FOUND, L_PROBE_KEY_MISS
113
+
114
+ L_PROBE_FOUND:
115
+ store out_index+0, index as u64
116
+ store out_found+0, 1 as u64
117
+ !key_match
118
+ !slot_key
119
+ !slot_hash
120
+ !hash_match
121
+ !is_empty
122
+ !state
123
+ !slot
124
+ !slot_off
125
+ !index
126
+ !remaining
127
+ jmp L_PROBE_END
128
+
129
+ L_PROBE_KEY_MISS:
130
+ !key_match
131
+ !slot_key
132
+ jmp L_PROBE_STEP
133
+
134
+ L_PROBE_EMPTY:
135
+ store out_index+0, index as u64
136
+ !is_empty
137
+ !state
138
+ !slot
139
+ !slot_off
140
+ !index
141
+ !remaining
142
+ jmp L_PROBE_END
143
+
144
+ L_PROBE_EXHAUSTED:
145
+ current_index = load index_slot+0 as u64
146
+ store out_index+0, current_index as u64
147
+ !current_index
148
+ !remaining
149
+ !exhausted
150
+ jmp L_PROBE_END
151
+
152
+ L_PROBE_END:
153
+ !cap_is_zero
154
+ !slots
155
+ !cap
156
+ !hash
157
+ !key
158
+ !out_index
159
+ !out_found
160
+ return
161
+
162
+ @map_table_insert(&slots: ptr, cap: u64, hash: u64, &key: ptr, &value: ptr) -> void:
163
+ L_ENTRY:
164
+ probe_index_slot = stack_alloc 8
165
+ probe_found_slot = stack_alloc 8
166
+ call @map_table_probe(&slots, cap, hash, &key, &probe_index_slot, &probe_found_slot)
167
+ probe_index = load probe_index_slot+0 as u64
168
+ slot_off = mul probe_index, HashMapSlot_SIZE
169
+ slot = ptr_add slots, slot_off
170
+ store slot+HashMapSlot_hash, hash as u64
171
+ store slot+HashMapSlot_key, key as ptr
172
+ store slot+HashMapSlot_value, value as ptr
173
+ store slot+HashMapSlot_state, HashMap_STATE_FILLED as u8
174
+ !slot
175
+ !slot_off
176
+ !probe_index
177
+ !slots
178
+ !cap
179
+ !hash
180
+ !key
181
+ !value
182
+ return
183
+
184
+ @map_next_capacity(requested: u64) -> u64:
185
+ L_ENTRY:
186
+ cap = HashMap_INITIAL_CAP
187
+ requested_is_zero = eq requested, 0
188
+ br requested_is_zero -> L_NEXT_CAP_ZERO, L_NEXT_CAP_LOOP
189
+
190
+ L_NEXT_CAP_LOOP:
191
+ cap_ge_requested = uge cap, requested
192
+ br cap_ge_requested -> L_NEXT_CAP_DONE, L_NEXT_CAP_GROW
193
+
194
+ L_NEXT_CAP_GROW:
195
+ EXPAND NUM_U64_CHECKED_ADD next_cap_ok, next_cap, cap, cap
196
+ br next_cap_ok -> L_NEXT_CAP_GROW_OK, L_NEXT_CAP_OVERFLOW
197
+
198
+ L_NEXT_CAP_OVERFLOW:
199
+ panic(1301)
200
+
201
+ L_NEXT_CAP_GROW_OK:
202
+ cap = next_cap
203
+ !next_cap_ok
204
+ !cap_ge_requested
205
+ jmp L_NEXT_CAP_LOOP
206
+
207
+ L_NEXT_CAP_DONE:
208
+ !cap_ge_requested
209
+ !requested_is_zero
210
+ !requested
211
+ return cap
212
+
213
+ L_NEXT_CAP_ZERO:
214
+ !requested_is_zero
215
+ !requested
216
+ return 0
217
+
218
+ @map_rehash(&map: ptr, new_cap: u64) -> void:
219
+ L_ENTRY:
220
+ old_slots = take map+HashMap_slots
221
+ old_cap = load map+HashMap_cap as u64
222
+ EXPAND NUM_U64_CHECKED_MUL new_bytes_ok, new_bytes, new_cap, HashMapSlot_SIZE
223
+ br new_bytes_ok -> L_REHASH_ALLOC, L_REHASH_OVERFLOW
224
+
225
+ L_REHASH_OVERFLOW:
226
+ panic(1302)
227
+
228
+ L_REHASH_ALLOC:
229
+ new_slots = alloc new_bytes
230
+ call @sa_mem_set(&new_slots, 0, new_bytes)
231
+ store map+HashMap_slots, new_slots as ptr
232
+ store map+HashMap_cap, new_cap as u64
233
+ store map+HashMap_len, 0 as u64
234
+ store map+HashMap_tombs, 0 as u64
235
+
236
+ old_idx_slot = stack_alloc 8
237
+ store old_idx_slot+0, 0 as u64
238
+ probe_idx_slot = stack_alloc 8
239
+ probe_found_slot = stack_alloc 8
240
+ old_cap_is_zero = eq old_cap, 0
241
+ br old_cap_is_zero -> L_REHASH_END_ZERO, L_REHASH_LOOP
242
+
243
+ L_REHASH_LOOP:
244
+ old_idx = load old_idx_slot+0 as u64
245
+ done = eq old_idx, old_cap
246
+ br done -> L_REHASH_END, L_REHASH_BODY
247
+
248
+ L_REHASH_BODY:
249
+ old_slot_off = mul old_idx, HashMapSlot_SIZE
250
+ old_slot = ptr_add old_slots, old_slot_off
251
+ state = load old_slot+HashMapSlot_state as u8
252
+ is_filled = eq state, HashMap_STATE_FILLED
253
+ br is_filled -> L_REHASH_INSERT, L_REHASH_NEXT
254
+
255
+ L_REHASH_INSERT:
256
+ old_hash = load old_slot+HashMapSlot_hash as u64
257
+ old_key = load old_slot+HashMapSlot_key as ptr
258
+ old_value = load old_slot+HashMapSlot_value as ptr
259
+ call @map_table_insert(&new_slots, new_cap, old_hash, &old_key, &old_value)
260
+ cur_len = load map+HashMap_len as u64
261
+ next_len = add cur_len, 1
262
+ store map+HashMap_len, next_len as u64
263
+ !old_hash
264
+ !old_key
265
+ !old_value
266
+ !cur_len
267
+ !next_len
268
+ jmp L_REHASH_NEXT
269
+
270
+ L_REHASH_NEXT:
271
+ next_old_idx = add old_idx, 1
272
+ store old_idx_slot+0, next_old_idx as u64
273
+ !old_idx
274
+ !done
275
+ !old_slot_off
276
+ !old_slot
277
+ !state
278
+ !is_filled
279
+ !next_old_idx
280
+ jmp L_REHASH_LOOP
281
+
282
+ L_REHASH_END:
283
+ !old_slots
284
+ !old_cap
285
+ !new_bytes
286
+ !new_bytes_ok
287
+ !old_cap_is_zero
288
+ return
289
+
290
+ L_REHASH_END_ZERO:
291
+ !old_slots
292
+ !old_cap
293
+ !new_bytes
294
+ !new_bytes_ok
295
+ !old_cap_is_zero
296
+ return
297
+
298
+ @map_probe_existing(&map: ptr, &key: ptr, &out_slot: ptr) -> i32:
299
+ L_ENTRY:
300
+ slots = load map+HashMap_slots as ptr
301
+ cap = load map+HashMap_cap as u64
302
+ cap_is_zero = eq cap, 0
303
+ br cap_is_zero -> L_PROBE_EXISTING_ZERO, L_PROBE_EXISTING_RUN
304
+
305
+ L_PROBE_EXISTING_RUN:
306
+ seed = load map+HashMap_seed as u64
307
+ hash = call @map_hash_ptr_seed(&key, seed)
308
+ probe_index_slot = stack_alloc 8
309
+ probe_found_slot = stack_alloc 8
310
+ call @map_table_probe(&slots, cap, hash, &key, &probe_index_slot, &probe_found_slot)
311
+ probe_found = load probe_found_slot+0 as u64
312
+ found = ne probe_found, 0
313
+ br found -> L_PROBE_EXISTING_HIT, L_PROBE_EXISTING_MISS
314
+
315
+ L_PROBE_EXISTING_HIT:
316
+ probe_index = load probe_index_slot+0 as u64
317
+ slot_off = mul probe_index, HashMapSlot_SIZE
318
+ slot = ptr_add slots, slot_off
319
+ store out_slot+0, slot as ptr
320
+ !slot
321
+ !slot_off
322
+ !probe_index
323
+ !found
324
+ !probe_found
325
+ !hash
326
+ !seed
327
+ !cap_is_zero
328
+ !cap
329
+ !slots
330
+ !out_slot
331
+ !key
332
+ !map
333
+ return 1
334
+
335
+ L_PROBE_EXISTING_MISS:
336
+ store out_slot+0, 0 as ptr
337
+ !found
338
+ !probe_found
339
+ !hash
340
+ !seed
341
+ !cap_is_zero
342
+ !cap
343
+ !slots
344
+ !out_slot
345
+ !key
346
+ !map
347
+ return 0
348
+
349
+ L_PROBE_EXISTING_ZERO:
350
+ store out_slot+0, 0 as ptr
351
+ !cap_is_zero
352
+ !cap
353
+ !slots
354
+ !out_slot
355
+ !key
356
+ !map
357
+ return 0
358
+
359
+ @export sa_map_new() -> ^ptr:
360
+ L_ENTRY:
361
+ map = alloc HashMap_SIZE
362
+ store map+HashMap_slots, 0 as ptr
363
+ store map+HashMap_cap, 0 as u64
364
+ store map+HashMap_len, 0 as u64
365
+ store map+HashMap_tombs, 0 as u64
366
+ store map+HashMap_seed, 0 as u64
367
+ return map
368
+
369
+ @export sa_map_with_seed(seed: u64) -> ^ptr:
370
+ L_ENTRY:
371
+ map = call @sa_map_new()
372
+ store map+HashMap_seed, seed as u64
373
+ !seed
374
+ return map
375
+
376
+ @export sa_map_with_capacity(cap: u64) -> ^ptr:
377
+ L_ENTRY:
378
+ map = call @sa_map_with_capacity_seed(cap, 0)
379
+ !cap
380
+ return map
381
+
382
+ @export sa_map_with_capacity_seed(cap: u64, seed: u64) -> ^ptr:
383
+ L_ENTRY:
384
+ map = call @sa_map_with_seed(seed)
385
+ cap_is_zero = eq cap, 0
386
+ br cap_is_zero -> L_WITH_CAP_ZERO, L_WITH_CAP_ALLOC
387
+
388
+ L_WITH_CAP_ALLOC:
389
+ next_cap = call @map_next_capacity(cap)
390
+ call @map_rehash(&map, next_cap)
391
+ !cap_is_zero
392
+ !seed
393
+ !cap
394
+ return map
395
+
396
+ L_WITH_CAP_ZERO:
397
+ !cap_is_zero
398
+ !seed
399
+ !cap
400
+ return map
401
+
402
+ @export sa_map_try_with_capacity(cap: u64, &out_map_slot: ptr) -> i32:
403
+ L_ENTRY:
404
+ map = call @sa_map_with_capacity(cap)
405
+ store out_map_slot+0, map as ptr
406
+ !map
407
+ !out_map_slot
408
+ !cap
409
+ return 1
410
+
411
+ @export sa_map_len(&map: ptr) -> u64:
412
+ L_ENTRY:
413
+ len = load map+HashMap_len as u64
414
+ !map
415
+ return len
416
+
417
+ @export sa_map_capacity(&map: ptr) -> u64:
418
+ L_ENTRY:
419
+ cap = load map+HashMap_cap as u64
420
+ !map
421
+ return cap
422
+
423
+ @export sa_map_reserve(&map: ptr, additional: u64) -> void:
424
+ L_ENTRY:
425
+ len = load map+HashMap_len as u64
426
+ cap = load map+HashMap_cap as u64
427
+ EXPAND NUM_U64_CHECKED_ADD needed_ok, needed, len, additional
428
+ br needed_ok -> L_RESERVE_NEEDED_OK, L_RESERVE_OVERFLOW
429
+
430
+ L_RESERVE_OVERFLOW:
431
+ panic(1303)
432
+
433
+ L_RESERVE_NEEDED_OK:
434
+ has_room = uge cap, needed
435
+ br has_room -> L_RESERVE_DONE, L_RESERVE_GROW
436
+
437
+ L_RESERVE_GROW:
438
+ next_cap = call @map_next_capacity(needed)
439
+ call @map_rehash(&map, next_cap)
440
+ !next_cap
441
+ !has_room
442
+ !needed
443
+ !needed_ok
444
+ !cap
445
+ !len
446
+ !additional
447
+ !map
448
+ return
449
+
450
+ L_RESERVE_DONE:
451
+ !has_room
452
+ !needed
453
+ !needed_ok
454
+ !cap
455
+ !len
456
+ !additional
457
+ !map
458
+ return
459
+
460
+ @export sa_map_try_reserve(&map: ptr, additional: u64) -> i32:
461
+ L_ENTRY:
462
+ call @sa_map_reserve(&map, additional)
463
+ !additional
464
+ !map
465
+ return 1
466
+
467
+ @export sa_map_shrink_to(&map: ptr, min_capacity: u64) -> void:
468
+ L_ENTRY:
469
+ len = load map+HashMap_len as u64
470
+ cap = load map+HashMap_cap as u64
471
+ keep_len = uge len, min_capacity
472
+ br keep_len -> L_SHRINK_TO_TARGET_LEN, L_SHRINK_TO_TARGET_MIN
473
+
474
+ L_SHRINK_TO_TARGET_LEN:
475
+ requested = add len, 0
476
+ jmp L_SHRINK_TO_PLAN
477
+
478
+ L_SHRINK_TO_TARGET_MIN:
479
+ requested = add min_capacity, 0
480
+
481
+ L_SHRINK_TO_PLAN:
482
+ target_cap = call @map_next_capacity(requested)
483
+ target_zero = eq target_cap, 0
484
+ br target_zero -> L_SHRINK_TO_ZERO, L_SHRINK_TO_CHECK
485
+
486
+ L_SHRINK_TO_ZERO:
487
+ call @sa_map_shrink_to_fit(&map)
488
+ !target_zero
489
+ !target_cap
490
+ !requested
491
+ !keep_len
492
+ !cap
493
+ !len
494
+ !min_capacity
495
+ !map
496
+ return
497
+
498
+ L_SHRINK_TO_CHECK:
499
+ should_shrink = ult target_cap, cap
500
+ br should_shrink -> L_SHRINK_TO_REHASH, L_SHRINK_TO_DONE
501
+
502
+ L_SHRINK_TO_REHASH:
503
+ call @map_rehash(&map, target_cap)
504
+ !should_shrink
505
+ !target_zero
506
+ !target_cap
507
+ !requested
508
+ !keep_len
509
+ !cap
510
+ !len
511
+ !min_capacity
512
+ !map
513
+ return
514
+
515
+ L_SHRINK_TO_DONE:
516
+ !should_shrink
517
+ !target_zero
518
+ !target_cap
519
+ !requested
520
+ !keep_len
521
+ !cap
522
+ !len
523
+ !min_capacity
524
+ !map
525
+ return
526
+
527
+ @export sa_map_shrink_to_fit(&map: ptr) -> void:
528
+ L_ENTRY:
529
+ len = load map+HashMap_len as u64
530
+ cap = load map+HashMap_cap as u64
531
+ is_empty = eq len, 0
532
+ br is_empty -> L_SHRINK_EMPTY, L_SHRINK_NONEMPTY
533
+
534
+ L_SHRINK_NONEMPTY:
535
+ next_cap = call @map_next_capacity(len)
536
+ needs_rehash = ne cap, next_cap
537
+ br needs_rehash -> L_SHRINK_REHASH, L_SHRINK_DONE
538
+
539
+ L_SHRINK_REHASH:
540
+ call @map_rehash(&map, next_cap)
541
+ !needs_rehash
542
+ !next_cap
543
+ !is_empty
544
+ !cap
545
+ !len
546
+ !map
547
+ return
548
+
549
+ L_SHRINK_DONE:
550
+ !needs_rehash
551
+ !next_cap
552
+ !is_empty
553
+ !cap
554
+ !len
555
+ !map
556
+ return
557
+
558
+ L_SHRINK_EMPTY:
559
+ slots = take map+HashMap_slots
560
+ has_slots = ne slots, 0
561
+ br has_slots -> L_SHRINK_FREE, L_SHRINK_RESET
562
+
563
+ L_SHRINK_FREE:
564
+ !slots
565
+ store map+HashMap_slots, 0 as ptr
566
+ store map+HashMap_cap, 0 as u64
567
+ store map+HashMap_len, 0 as u64
568
+ store map+HashMap_tombs, 0 as u64
569
+ !has_slots
570
+ !is_empty
571
+ !cap
572
+ !len
573
+ !map
574
+ return
575
+
576
+ L_SHRINK_RESET:
577
+ store map+HashMap_slots, 0 as ptr
578
+ store map+HashMap_cap, 0 as u64
579
+ store map+HashMap_len, 0 as u64
580
+ store map+HashMap_tombs, 0 as u64
581
+ !has_slots
582
+ !slots
583
+ !is_empty
584
+ !cap
585
+ !len
586
+ !map
587
+ return
588
+
589
+ @export sa_map_is_empty(&map: ptr) -> i32:
590
+ L_ENTRY:
591
+ len = load map+HashMap_len as u64
592
+ empty = eq len, 0
593
+ result = empty as i32
594
+ !len
595
+ !map
596
+ return result
597
+
598
+ @export sa_map_contains_key(&map: ptr, &key: ptr) -> i32:
599
+ L_ENTRY:
600
+ slots = load map+HashMap_slots as ptr
601
+ cap = load map+HashMap_cap as u64
602
+ cap_is_zero = eq cap, 0
603
+ br cap_is_zero -> L_CONTAINS_MISS_ZERO, L_CONTAINS_PROBE
604
+
605
+ L_CONTAINS_PROBE:
606
+ seed = load map+HashMap_seed as u64
607
+ hash = call @map_hash_ptr_seed(&key, seed)
608
+ probe_index_slot = stack_alloc 8
609
+ probe_found_slot = stack_alloc 8
610
+ call @map_table_probe(&slots, cap, hash, &key, &probe_index_slot, &probe_found_slot)
611
+ probe_found = load probe_found_slot+0 as u64
612
+ found = ne probe_found, 0
613
+ result = found as i32
614
+ !probe_found
615
+ !hash
616
+ !seed
617
+ !key
618
+ !cap
619
+ !cap_is_zero
620
+ !slots
621
+ return result
622
+
623
+ L_CONTAINS_MISS_ZERO:
624
+ !cap
625
+ !cap_is_zero
626
+ !key
627
+ !slots
628
+ return 0
629
+
630
+ @export sa_map_clear(&map: ptr) -> void:
631
+ L_ENTRY:
632
+ slots = load map+HashMap_slots as ptr
633
+ cap = load map+HashMap_cap as u64
634
+ EXPAND NUM_U64_CHECKED_MUL clear_bytes_ok, bytes, cap, HashMapSlot_SIZE
635
+ br clear_bytes_ok -> L_CLEAR_BYTES_OK, L_CLEAR_BYTES_OVERFLOW
636
+
637
+ L_CLEAR_BYTES_OVERFLOW:
638
+ panic(1305)
639
+
640
+ L_CLEAR_BYTES_OK:
641
+ has_slots = ne slots, 0
642
+ br has_slots -> L_CLEAR_SLOTS, L_CLEAR_DONE
643
+
644
+ L_CLEAR_SLOTS:
645
+ call @sa_mem_set(&slots, 0, bytes)
646
+ jmp L_CLEAR_DONE
647
+
648
+ L_CLEAR_DONE:
649
+ store map+HashMap_len, 0 as u64
650
+ store map+HashMap_tombs, 0 as u64
651
+ !clear_bytes_ok
652
+ !bytes
653
+ !has_slots
654
+ !cap
655
+ !slots
656
+ !map
657
+ return
658
+
659
+ @export sa_map_free(^map: ptr) -> void:
660
+ L_ENTRY:
661
+ slots = take map+HashMap_slots
662
+ has_slots = ne slots, 0
663
+ br has_slots -> L_FREE_SLOTS, L_FREE_MAP
664
+
665
+ L_FREE_SLOTS:
666
+ !slots
667
+
668
+ L_FREE_MAP:
669
+ !has_slots
670
+ !map
671
+ return
672
+
673
+ @export sa_map_put(&map: ptr, &key: ptr, &value: ptr) -> void:
674
+ L_ENTRY:
675
+ slots = load map+HashMap_slots as ptr
676
+ cap = load map+HashMap_cap as u64
677
+ len = load map+HashMap_len as u64
678
+ tombs = load map+HashMap_tombs as u64
679
+ used = add len, tombs
680
+ used_twice = shl used, 1
681
+ cap_is_zero = eq cap, 0
682
+ pressure = uge used_twice, cap
683
+ grow = or cap_is_zero, pressure
684
+ br grow -> L_PUT_GROW, L_PUT_PROBE_DIRECT
685
+
686
+ L_PUT_GROW:
687
+ br cap_is_zero -> L_PUT_GROW_INIT, L_PUT_GROW_DOUBLE
688
+
689
+ L_PUT_GROW_INIT:
690
+ next_cap_raw = HashMap_INITIAL_CAP
691
+ next_cap = next_cap_raw
692
+ jmp L_PUT_GROW_REHASH
693
+
694
+ L_PUT_GROW_DOUBLE:
695
+ EXPAND NUM_U64_CHECKED_ADD next_cap_raw_ok, next_cap_raw, cap, cap
696
+ br next_cap_raw_ok -> L_PUT_GROW_DOUBLE_OK, L_PUT_GROW_DOUBLE_OVERFLOW
697
+
698
+ L_PUT_GROW_DOUBLE_OVERFLOW:
699
+ panic(1304)
700
+
701
+ L_PUT_GROW_DOUBLE_OK:
702
+ next_cap = next_cap_raw
703
+ !next_cap_raw_ok
704
+ jmp L_PUT_GROW_REHASH
705
+
706
+ L_PUT_GROW_REHASH:
707
+ !cap
708
+ !len
709
+ !tombs
710
+ !cap_is_zero
711
+ !slots
712
+ call @map_rehash(&map, next_cap)
713
+ slots = load map+HashMap_slots as ptr
714
+ cap = load map+HashMap_cap as u64
715
+ len = load map+HashMap_len as u64
716
+ tombs = load map+HashMap_tombs as u64
717
+ !next_cap
718
+ jmp L_PUT_PROBE
719
+
720
+ L_PUT_PROBE_DIRECT:
721
+ !cap_is_zero
722
+ jmp L_PUT_PROBE
723
+
724
+ L_PUT_PROBE:
725
+ seed = load map+HashMap_seed as u64
726
+ hash = call @map_hash_ptr_seed(&key, seed)
727
+ probe_index_slot = stack_alloc 8
728
+ probe_found_slot = stack_alloc 8
729
+ call @map_table_probe(&slots, cap, hash, &key, &probe_index_slot, &probe_found_slot)
730
+ probe_index = load probe_index_slot+0 as u64
731
+ probe_found = load probe_found_slot+0 as u64
732
+ slot_off = mul probe_index, HashMapSlot_SIZE
733
+ slot = ptr_add slots, slot_off
734
+ already_found = ne probe_found, 0
735
+ br already_found -> L_PUT_UPDATE, L_PUT_INSERT
736
+
737
+ L_PUT_UPDATE:
738
+ store slot+HashMapSlot_value, value as ptr
739
+ jmp L_PUT_END
740
+
741
+ L_PUT_INSERT:
742
+ slot_state = load slot+HashMapSlot_state as u8
743
+ tomb_slot = eq slot_state, HashMap_STATE_TOMB
744
+ br tomb_slot -> L_PUT_INSERT_TOMB, L_PUT_INSERT_EMPTY
745
+
746
+ L_PUT_INSERT_TOMB:
747
+ next_tombs = sub tombs, 1
748
+ store map+HashMap_tombs, next_tombs as u64
749
+ !next_tombs
750
+ jmp L_PUT_INSERT_EMPTY
751
+
752
+ L_PUT_INSERT_EMPTY:
753
+ next_len = add len, 1
754
+ store map+HashMap_len, next_len as u64
755
+ store slot+HashMapSlot_hash, hash as u64
756
+ store slot+HashMapSlot_key, key as ptr
757
+ store slot+HashMapSlot_value, value as ptr
758
+ store slot+HashMapSlot_state, HashMap_STATE_FILLED as u8
759
+ !next_len
760
+ !slot_state
761
+ !tomb_slot
762
+ !probe_found
763
+ !probe_index
764
+ !slot_off
765
+ !slot
766
+ !hash
767
+ !seed
768
+ !key
769
+ !value
770
+ !cap
771
+ !len
772
+ !tombs
773
+ !used
774
+ !used_twice
775
+ !pressure
776
+ !grow
777
+ !slots
778
+ return
779
+
780
+ L_PUT_END:
781
+ !probe_found
782
+ !probe_index
783
+ !slot_off
784
+ !slot
785
+ !hash
786
+ !seed
787
+ !key
788
+ !value
789
+ !cap
790
+ !len
791
+ !tombs
792
+ !used
793
+ !used_twice
794
+ !pressure
795
+ !grow
796
+ !slots
797
+ return
798
+
799
+ @export sa_map_get(&map: ptr, &key: ptr) -> &ptr:
800
+ L_ENTRY:
801
+ slots = load map+HashMap_slots as ptr
802
+ cap = load map+HashMap_cap as u64
803
+ cap_is_zero = eq cap, 0
804
+ br cap_is_zero -> L_GET_MISS_ZERO, L_GET_PROBE
805
+
806
+ L_GET_PROBE:
807
+ seed = load map+HashMap_seed as u64
808
+ hash = call @map_hash_ptr_seed(&key, seed)
809
+ probe_index_slot = stack_alloc 8
810
+ probe_found_slot = stack_alloc 8
811
+ call @map_table_probe(&slots, cap, hash, &key, &probe_index_slot, &probe_found_slot)
812
+ probe_found = load probe_found_slot+0 as u64
813
+ found = ne probe_found, 0
814
+ br found -> L_GET_HIT, L_GET_MISS_PROBE
815
+
816
+ L_GET_HIT:
817
+ probe_index = load probe_index_slot+0 as u64
818
+ slot_off = mul probe_index, HashMapSlot_SIZE
819
+ slot = ptr_add slots, slot_off
820
+ value = load slot+HashMapSlot_value as ptr
821
+ !slot
822
+ !slot_off
823
+ !probe_index
824
+ !probe_found
825
+ !hash
826
+ !seed
827
+ !key
828
+ !cap
829
+ !cap_is_zero
830
+ !slots
831
+ return value
832
+
833
+ L_GET_MISS_PROBE:
834
+ !probe_found
835
+ !hash
836
+ !seed
837
+ !key
838
+ !cap
839
+ !cap_is_zero
840
+ !slots
841
+ return 0
842
+
843
+ L_GET_MISS_ZERO:
844
+ !cap
845
+ !cap_is_zero
846
+ !key
847
+ !slots
848
+ return 0
849
+
850
+ @export sa_map_try_get(&map: ptr, &key: ptr, &out_value_slot: ptr) -> i32:
851
+ L_ENTRY:
852
+ slot_slot = stack_alloc 8
853
+ found = call @map_probe_existing(&map, &key, &slot_slot)
854
+ found_nonzero = ne found, 0
855
+ br found_nonzero -> L_TRY_GET_HIT, L_TRY_GET_MISS
856
+
857
+ L_TRY_GET_HIT:
858
+ slot = load slot_slot+0 as ptr
859
+ value = load slot+HashMapSlot_value as ptr
860
+ store out_value_slot+0, value as ptr
861
+ !value
862
+ !slot
863
+ !found_nonzero
864
+ !found
865
+ !out_value_slot
866
+ !key
867
+ !map
868
+ return 1
869
+
870
+ L_TRY_GET_MISS:
871
+ store out_value_slot+0, 0 as ptr
872
+ !found_nonzero
873
+ !found
874
+ !out_value_slot
875
+ !key
876
+ !map
877
+ return 0
878
+
879
+ @export sa_map_try_get_key_value(&map: ptr, &key: ptr, &out_key_slot: ptr, &out_value_slot: ptr) -> i32:
880
+ L_ENTRY:
881
+ slot_slot = stack_alloc 8
882
+ found = call @map_probe_existing(&map, &key, &slot_slot)
883
+ found_nonzero = ne found, 0
884
+ br found_nonzero -> L_GET_KEY_VALUE_HIT, L_GET_KEY_VALUE_MISS
885
+
886
+ L_GET_KEY_VALUE_HIT:
887
+ slot = load slot_slot+0 as ptr
888
+ stored_key = load slot+HashMapSlot_key as ptr
889
+ stored_value = load slot+HashMapSlot_value as ptr
890
+ store out_key_slot+0, stored_key as ptr
891
+ store out_value_slot+0, stored_value as ptr
892
+ !stored_value
893
+ !stored_key
894
+ !slot
895
+ !found_nonzero
896
+ !found
897
+ !out_value_slot
898
+ !out_key_slot
899
+ !key
900
+ !map
901
+ return 1
902
+
903
+ L_GET_KEY_VALUE_MISS:
904
+ store out_key_slot+0, 0 as ptr
905
+ store out_value_slot+0, 0 as ptr
906
+ !found_nonzero
907
+ !found
908
+ !out_value_slot
909
+ !out_key_slot
910
+ !key
911
+ !map
912
+ return 0
913
+
914
+ @export sa_map_get_mut_ptr(&map: ptr, &key: ptr, &out_ptr_slot: ptr) -> i32:
915
+ L_ENTRY:
916
+ slot_slot = stack_alloc 8
917
+ found = call @map_probe_existing(&map, &key, &slot_slot)
918
+ found_nonzero = ne found, 0
919
+ br found_nonzero -> L_GET_MUT_HIT, L_GET_MUT_MISS
920
+
921
+ L_GET_MUT_HIT:
922
+ slot = load slot_slot+0 as ptr
923
+ value_ptr = ptr_add slot, HashMapSlot_value
924
+ store out_ptr_slot+0, value_ptr as ptr
925
+ !value_ptr
926
+ !slot
927
+ !found_nonzero
928
+ !found
929
+ !out_ptr_slot
930
+ !key
931
+ !map
932
+ return 1
933
+
934
+ L_GET_MUT_MISS:
935
+ store out_ptr_slot+0, 0 as ptr
936
+ !found_nonzero
937
+ !found
938
+ !out_ptr_slot
939
+ !key
940
+ !map
941
+ return 0
942
+
943
+ @export sa_map_try_get_disjoint_mut_ptrs(&map: ptr, &key_a: ptr, &key_b: ptr, &out_ptr_a_slot: ptr, &out_ptr_b_slot: ptr) -> i32:
944
+ L_ENTRY:
945
+ same_key = eq key_a, key_b
946
+ br same_key -> L_DISJOINT_MUT_SAME, L_DISJOINT_MUT_LOOKUP_A
947
+
948
+ L_DISJOINT_MUT_LOOKUP_A:
949
+ found_a = call @sa_map_get_mut_ptr(&map, &key_a, &out_ptr_a_slot)
950
+ has_a = ne found_a, 0
951
+ br has_a -> L_DISJOINT_MUT_LOOKUP_B, L_DISJOINT_MUT_MISS_A
952
+
953
+ L_DISJOINT_MUT_LOOKUP_B:
954
+ found_b = call @sa_map_get_mut_ptr(&map, &key_b, &out_ptr_b_slot)
955
+ has_b = ne found_b, 0
956
+ br has_b -> L_DISJOINT_MUT_HIT, L_DISJOINT_MUT_MISS_B
957
+
958
+ L_DISJOINT_MUT_HIT:
959
+ !has_b
960
+ !found_b
961
+ !has_a
962
+ !found_a
963
+ !same_key
964
+ !out_ptr_b_slot
965
+ !out_ptr_a_slot
966
+ !key_b
967
+ !key_a
968
+ !map
969
+ return 1
970
+
971
+ L_DISJOINT_MUT_MISS_B:
972
+ store out_ptr_a_slot+0, 0 as ptr
973
+ store out_ptr_b_slot+0, 0 as ptr
974
+ !has_b
975
+ !found_b
976
+ !has_a
977
+ !found_a
978
+ !same_key
979
+ !out_ptr_b_slot
980
+ !out_ptr_a_slot
981
+ !key_b
982
+ !key_a
983
+ !map
984
+ return 0
985
+
986
+ L_DISJOINT_MUT_MISS_A:
987
+ store out_ptr_a_slot+0, 0 as ptr
988
+ store out_ptr_b_slot+0, 0 as ptr
989
+ !has_a
990
+ !found_a
991
+ !same_key
992
+ !out_ptr_b_slot
993
+ !out_ptr_a_slot
994
+ !key_b
995
+ !key_a
996
+ !map
997
+ return 0
998
+
999
+ L_DISJOINT_MUT_SAME:
1000
+ store out_ptr_a_slot+0, 0 as ptr
1001
+ store out_ptr_b_slot+0, 0 as ptr
1002
+ !same_key
1003
+ !out_ptr_b_slot
1004
+ !out_ptr_a_slot
1005
+ !key_b
1006
+ !key_a
1007
+ !map
1008
+ return 0
1009
+
1010
+ @export sa_map_insert(&map: ptr, &key: ptr, &value: ptr, &out_old_value_slot: ptr) -> i32:
1011
+ L_ENTRY:
1012
+ replaced = call @sa_map_try_get(&map, &key, &out_old_value_slot)
1013
+ call @sa_map_put(&map, &key, &value)
1014
+ !out_old_value_slot
1015
+ !value
1016
+ !key
1017
+ !map
1018
+ return replaced
1019
+
1020
+ @export sa_map_try_insert(&map: ptr, &key: ptr, &value: ptr, &out_value_ptr_slot: ptr) -> i32:
1021
+ L_ENTRY:
1022
+ slot_slot = stack_alloc 8
1023
+ found = call @map_probe_existing(&map, &key, &slot_slot)
1024
+ found_nonzero = ne found, 0
1025
+ br found_nonzero -> L_TRY_INSERT_EXISTS, L_TRY_INSERT_NEW
1026
+
1027
+ L_TRY_INSERT_EXISTS:
1028
+ slot = load slot_slot+0 as ptr
1029
+ value_ptr = ptr_add slot, HashMapSlot_value
1030
+ store out_value_ptr_slot+0, value_ptr as ptr
1031
+ !value_ptr
1032
+ !slot
1033
+ !found_nonzero
1034
+ !found
1035
+ !out_value_ptr_slot
1036
+ !value
1037
+ !key
1038
+ !map
1039
+ return 0
1040
+
1041
+ L_TRY_INSERT_NEW:
1042
+ call @sa_map_put(&map, &key, &value)
1043
+ inserted_found = call @map_probe_existing(&map, &key, &slot_slot)
1044
+ slot = load slot_slot+0 as ptr
1045
+ value_ptr = ptr_add slot, HashMapSlot_value
1046
+ store out_value_ptr_slot+0, value_ptr as ptr
1047
+ !value_ptr
1048
+ !slot
1049
+ !inserted_found
1050
+ !found_nonzero
1051
+ !found
1052
+ !out_value_ptr_slot
1053
+ !value
1054
+ !key
1055
+ !map
1056
+ return 1
1057
+
1058
+ @export sa_map_keys_vec(&map: ptr) -> ^ptr:
1059
+ L_ENTRY:
1060
+ len = load map+HashMap_len as u64
1061
+ out_vec = call @sa_vec_with_capacity(len, 8)
1062
+ slots = load map+HashMap_slots as ptr
1063
+ cap = load map+HashMap_cap as u64
1064
+ idx_slot = stack_alloc 8
1065
+ store idx_slot+0, 0 as u64
1066
+ jmp L_MAP_KEYS_HEAD
1067
+
1068
+ L_MAP_KEYS_HEAD:
1069
+ idx = load idx_slot+0 as u64
1070
+ done = eq idx, cap
1071
+ br done -> L_MAP_KEYS_DONE, L_MAP_KEYS_BODY
1072
+
1073
+ L_MAP_KEYS_BODY:
1074
+ slot_off = mul idx, HashMapSlot_SIZE
1075
+ slot = ptr_add slots, slot_off
1076
+ state = load slot+HashMapSlot_state as u8
1077
+ filled = eq state, HashMap_STATE_FILLED
1078
+ br filled -> L_MAP_KEYS_PUSH, L_MAP_KEYS_NEXT
1079
+
1080
+ L_MAP_KEYS_PUSH:
1081
+ key = load slot+HashMapSlot_key as ptr
1082
+ key_bits = bitcast key as u64
1083
+ out_vec = call @sa_vec_push(^out_vec, key_bits, 8)
1084
+ !key_bits
1085
+ !key
1086
+ jmp L_MAP_KEYS_NEXT
1087
+
1088
+ L_MAP_KEYS_NEXT:
1089
+ next_idx = add idx, 1
1090
+ store idx_slot+0, next_idx as u64
1091
+ !next_idx
1092
+ !filled
1093
+ !state
1094
+ !slot
1095
+ !slot_off
1096
+ !done
1097
+ !idx
1098
+ jmp L_MAP_KEYS_HEAD
1099
+
1100
+ L_MAP_KEYS_DONE:
1101
+ !done
1102
+ !idx
1103
+ !cap
1104
+ !slots
1105
+ !len
1106
+ !map
1107
+ return out_vec
1108
+
1109
+ @export sa_map_values_vec(&map: ptr) -> ^ptr:
1110
+ L_ENTRY:
1111
+ len = load map+HashMap_len as u64
1112
+ out_vec = call @sa_vec_with_capacity(len, 8)
1113
+ slots = load map+HashMap_slots as ptr
1114
+ cap = load map+HashMap_cap as u64
1115
+ idx_slot = stack_alloc 8
1116
+ store idx_slot+0, 0 as u64
1117
+ jmp L_MAP_VALUES_HEAD
1118
+
1119
+ L_MAP_VALUES_HEAD:
1120
+ idx = load idx_slot+0 as u64
1121
+ done = eq idx, cap
1122
+ br done -> L_MAP_VALUES_DONE, L_MAP_VALUES_BODY
1123
+
1124
+ L_MAP_VALUES_BODY:
1125
+ slot_off = mul idx, HashMapSlot_SIZE
1126
+ slot = ptr_add slots, slot_off
1127
+ state = load slot+HashMapSlot_state as u8
1128
+ filled = eq state, HashMap_STATE_FILLED
1129
+ br filled -> L_MAP_VALUES_PUSH, L_MAP_VALUES_NEXT
1130
+
1131
+ L_MAP_VALUES_PUSH:
1132
+ value = load slot+HashMapSlot_value as ptr
1133
+ value_bits = bitcast value as u64
1134
+ out_vec = call @sa_vec_push(^out_vec, value_bits, 8)
1135
+ !value_bits
1136
+ !value
1137
+ jmp L_MAP_VALUES_NEXT
1138
+
1139
+ L_MAP_VALUES_NEXT:
1140
+ next_idx = add idx, 1
1141
+ store idx_slot+0, next_idx as u64
1142
+ !next_idx
1143
+ !filled
1144
+ !state
1145
+ !slot
1146
+ !slot_off
1147
+ !done
1148
+ !idx
1149
+ jmp L_MAP_VALUES_HEAD
1150
+
1151
+ L_MAP_VALUES_DONE:
1152
+ !done
1153
+ !idx
1154
+ !cap
1155
+ !slots
1156
+ !len
1157
+ !map
1158
+ return out_vec
1159
+
1160
+ @export sa_map_value_mut_ptrs_vec(&map: ptr) -> ^ptr:
1161
+ L_ENTRY:
1162
+ len = load map+HashMap_len as u64
1163
+ out_vec = call @sa_vec_with_capacity(len, 8)
1164
+ slots = load map+HashMap_slots as ptr
1165
+ cap = load map+HashMap_cap as u64
1166
+ idx_slot = stack_alloc 8
1167
+ store idx_slot+0, 0 as u64
1168
+ jmp L_MAP_VALUE_MUT_PTRS_HEAD
1169
+
1170
+ L_MAP_VALUE_MUT_PTRS_HEAD:
1171
+ idx = load idx_slot+0 as u64
1172
+ done = eq idx, cap
1173
+ br done -> L_MAP_VALUE_MUT_PTRS_DONE, L_MAP_VALUE_MUT_PTRS_BODY
1174
+
1175
+ L_MAP_VALUE_MUT_PTRS_BODY:
1176
+ slot_off = mul idx, HashMapSlot_SIZE
1177
+ slot = ptr_add slots, slot_off
1178
+ state = load slot+HashMapSlot_state as u8
1179
+ filled = eq state, HashMap_STATE_FILLED
1180
+ br filled -> L_MAP_VALUE_MUT_PTRS_PUSH, L_MAP_VALUE_MUT_PTRS_NEXT
1181
+
1182
+ L_MAP_VALUE_MUT_PTRS_PUSH:
1183
+ value_ptr = ptr_add slot, HashMapSlot_value
1184
+ value_ptr_bits = bitcast value_ptr as u64
1185
+ out_vec = call @sa_vec_push(^out_vec, value_ptr_bits, 8)
1186
+ !value_ptr_bits
1187
+ !value_ptr
1188
+ jmp L_MAP_VALUE_MUT_PTRS_NEXT
1189
+
1190
+ L_MAP_VALUE_MUT_PTRS_NEXT:
1191
+ next_idx = add idx, 1
1192
+ store idx_slot+0, next_idx as u64
1193
+ !next_idx
1194
+ !filled
1195
+ !state
1196
+ !slot
1197
+ !slot_off
1198
+ !done
1199
+ !idx
1200
+ jmp L_MAP_VALUE_MUT_PTRS_HEAD
1201
+
1202
+ L_MAP_VALUE_MUT_PTRS_DONE:
1203
+ !done
1204
+ !idx
1205
+ !cap
1206
+ !slots
1207
+ !len
1208
+ !map
1209
+ return out_vec
1210
+
1211
+ @export sa_map_iter_vec(&map: ptr) -> ^ptr:
1212
+ L_ENTRY:
1213
+ len = load map+HashMap_len as u64
1214
+ EXPAND NUM_U64_CHECKED_ADD map_iter_cap_hint_ok, map_iter_cap_hint, len, len
1215
+ br map_iter_cap_hint_ok -> L_MAP_ITER_CAP_OK, L_MAP_ITER_CAP_OVERFLOW
1216
+
1217
+ L_MAP_ITER_CAP_OVERFLOW:
1218
+ panic(1309)
1219
+
1220
+ L_MAP_ITER_CAP_OK:
1221
+ out_vec = call @sa_vec_with_capacity(map_iter_cap_hint, 8)
1222
+ slots = load map+HashMap_slots as ptr
1223
+ cap = load map+HashMap_cap as u64
1224
+ idx_slot = stack_alloc 8
1225
+ store idx_slot+0, 0 as u64
1226
+ jmp L_MAP_ITER_HEAD
1227
+
1228
+ L_MAP_ITER_HEAD:
1229
+ idx = load idx_slot+0 as u64
1230
+ done = eq idx, cap
1231
+ br done -> L_MAP_ITER_DONE, L_MAP_ITER_BODY
1232
+
1233
+ L_MAP_ITER_BODY:
1234
+ slot_off = mul idx, HashMapSlot_SIZE
1235
+ slot = ptr_add slots, slot_off
1236
+ state = load slot+HashMapSlot_state as u8
1237
+ filled = eq state, HashMap_STATE_FILLED
1238
+ br filled -> L_MAP_ITER_PUSH, L_MAP_ITER_NEXT
1239
+
1240
+ L_MAP_ITER_PUSH:
1241
+ key = load slot+HashMapSlot_key as ptr
1242
+ value = load slot+HashMapSlot_value as ptr
1243
+ key_bits = bitcast key as u64
1244
+ value_bits = bitcast value as u64
1245
+ out_vec = call @sa_vec_push(^out_vec, key_bits, 8)
1246
+ out_vec = call @sa_vec_push(^out_vec, value_bits, 8)
1247
+ !value_bits
1248
+ !key_bits
1249
+ !value
1250
+ !key
1251
+ jmp L_MAP_ITER_NEXT
1252
+
1253
+ L_MAP_ITER_NEXT:
1254
+ next_idx = add idx, 1
1255
+ store idx_slot+0, next_idx as u64
1256
+ !next_idx
1257
+ !filled
1258
+ !state
1259
+ !slot
1260
+ !slot_off
1261
+ !done
1262
+ !idx
1263
+ jmp L_MAP_ITER_HEAD
1264
+
1265
+ L_MAP_ITER_DONE:
1266
+ !done
1267
+ !idx
1268
+ !cap
1269
+ !slots
1270
+ !map_iter_cap_hint_ok
1271
+ !map_iter_cap_hint
1272
+ !len
1273
+ !map
1274
+ return out_vec
1275
+
1276
+ @export sa_map_iter_mut_ptrs_vec(&map: ptr) -> ^ptr:
1277
+ L_ENTRY:
1278
+ len = load map+HashMap_len as u64
1279
+ EXPAND NUM_U64_CHECKED_ADD map_iter_mut_cap_hint_ok, map_iter_mut_cap_hint, len, len
1280
+ br map_iter_mut_cap_hint_ok -> L_MAP_ITER_MUT_CAP_OK, L_MAP_ITER_MUT_CAP_OVERFLOW
1281
+
1282
+ L_MAP_ITER_MUT_CAP_OVERFLOW:
1283
+ panic(1310)
1284
+
1285
+ L_MAP_ITER_MUT_CAP_OK:
1286
+ out_vec = call @sa_vec_with_capacity(map_iter_mut_cap_hint, 8)
1287
+ slots = load map+HashMap_slots as ptr
1288
+ cap = load map+HashMap_cap as u64
1289
+ idx_slot = stack_alloc 8
1290
+ store idx_slot+0, 0 as u64
1291
+ jmp L_MAP_ITER_MUT_HEAD
1292
+
1293
+ L_MAP_ITER_MUT_HEAD:
1294
+ idx = load idx_slot+0 as u64
1295
+ done = eq idx, cap
1296
+ br done -> L_MAP_ITER_MUT_DONE, L_MAP_ITER_MUT_BODY
1297
+
1298
+ L_MAP_ITER_MUT_BODY:
1299
+ slot_off = mul idx, HashMapSlot_SIZE
1300
+ slot = ptr_add slots, slot_off
1301
+ state = load slot+HashMapSlot_state as u8
1302
+ filled = eq state, HashMap_STATE_FILLED
1303
+ br filled -> L_MAP_ITER_MUT_PUSH, L_MAP_ITER_MUT_NEXT
1304
+
1305
+ L_MAP_ITER_MUT_PUSH:
1306
+ key = load slot+HashMapSlot_key as ptr
1307
+ value_ptr = ptr_add slot, HashMapSlot_value
1308
+ key_bits = bitcast key as u64
1309
+ value_ptr_bits = bitcast value_ptr as u64
1310
+ out_vec = call @sa_vec_push(^out_vec, key_bits, 8)
1311
+ out_vec = call @sa_vec_push(^out_vec, value_ptr_bits, 8)
1312
+ !value_ptr_bits
1313
+ !key_bits
1314
+ !value_ptr
1315
+ !key
1316
+ jmp L_MAP_ITER_MUT_NEXT
1317
+
1318
+ L_MAP_ITER_MUT_NEXT:
1319
+ next_idx = add idx, 1
1320
+ store idx_slot+0, next_idx as u64
1321
+ !next_idx
1322
+ !filled
1323
+ !state
1324
+ !slot
1325
+ !slot_off
1326
+ !done
1327
+ !idx
1328
+ jmp L_MAP_ITER_MUT_HEAD
1329
+
1330
+ L_MAP_ITER_MUT_DONE:
1331
+ !done
1332
+ !idx
1333
+ !cap
1334
+ !slots
1335
+ !map_iter_mut_cap_hint_ok
1336
+ !map_iter_mut_cap_hint
1337
+ !len
1338
+ !map
1339
+ return out_vec
1340
+
1341
+ @export sa_map_remove_entry(&map: ptr, &key: ptr, &out_key_slot: ptr, &out_value_slot: ptr) -> i32:
1342
+ L_ENTRY:
1343
+ found = call @sa_map_try_get_key_value(&map, &key, &out_key_slot, &out_value_slot)
1344
+ found_nonzero = ne found, 0
1345
+ br found_nonzero -> L_REMOVE_ENTRY_HIT, L_REMOVE_ENTRY_MISS
1346
+
1347
+ L_REMOVE_ENTRY_HIT:
1348
+ removed = call @sa_map_del(&map, &key)
1349
+ !removed
1350
+ !found_nonzero
1351
+ !found
1352
+ !out_value_slot
1353
+ !out_key_slot
1354
+ !key
1355
+ !map
1356
+ return 1
1357
+
1358
+ L_REMOVE_ENTRY_MISS:
1359
+ !found_nonzero
1360
+ !found
1361
+ !out_value_slot
1362
+ !out_key_slot
1363
+ !key
1364
+ !map
1365
+ return 0
1366
+
1367
+ @export sa_map_del(&map: ptr, &key: ptr) -> &ptr:
1368
+ L_ENTRY:
1369
+ slots = load map+HashMap_slots as ptr
1370
+ cap = load map+HashMap_cap as u64
1371
+ len = load map+HashMap_len as u64
1372
+ tombs = load map+HashMap_tombs as u64
1373
+ cap_is_zero = eq cap, 0
1374
+ br cap_is_zero -> L_DEL_MISS_ZERO, L_DEL_PROBE
1375
+
1376
+ L_DEL_PROBE:
1377
+ seed = load map+HashMap_seed as u64
1378
+ hash = call @map_hash_ptr_seed(&key, seed)
1379
+ probe_index_slot = stack_alloc 8
1380
+ probe_found_slot = stack_alloc 8
1381
+ call @map_table_probe(&slots, cap, hash, &key, &probe_index_slot, &probe_found_slot)
1382
+ probe_found = load probe_found_slot+0 as u64
1383
+ found = ne probe_found, 0
1384
+ br found -> L_DEL_HIT, L_DEL_MISS_PROBE
1385
+
1386
+ L_DEL_HIT:
1387
+ probe_index = load probe_index_slot+0 as u64
1388
+ slot_off = mul probe_index, HashMapSlot_SIZE
1389
+ slot = ptr_add slots, slot_off
1390
+ value = load slot+HashMapSlot_value as ptr
1391
+ next_len = sub len, 1
1392
+ next_tombs = add tombs, 1
1393
+ store map+HashMap_len, next_len as u64
1394
+ store map+HashMap_tombs, next_tombs as u64
1395
+ store slot+HashMapSlot_hash, 0 as u64
1396
+ store slot+HashMapSlot_key, 0 as ptr
1397
+ store slot+HashMapSlot_value, 0 as ptr
1398
+ store slot+HashMapSlot_state, HashMap_STATE_TOMB as u8
1399
+ !slot
1400
+ !slot_off
1401
+ !probe_index
1402
+ !probe_found
1403
+ !hash
1404
+ !seed
1405
+ !cap
1406
+ !len
1407
+ !tombs
1408
+ !next_len
1409
+ !next_tombs
1410
+ !cap_is_zero
1411
+ !key
1412
+ !slots
1413
+ !map
1414
+ return value
1415
+
1416
+ L_DEL_MISS_PROBE:
1417
+ !probe_found
1418
+ !hash
1419
+ !seed
1420
+ !key
1421
+ !cap
1422
+ !len
1423
+ !tombs
1424
+ !cap_is_zero
1425
+ !slots
1426
+ !map
1427
+ return 0
1428
+
1429
+ L_DEL_MISS_ZERO:
1430
+ !cap
1431
+ !len
1432
+ !tombs
1433
+ !cap_is_zero
1434
+ !key
1435
+ !slots
1436
+ !map
1437
+ return 0
1438
+
1439
+ [MACRO] MAP_NEW %out_map
1440
+ %out_map = call @sa_map_new()
1441
+ [END_MACRO]
1442
+
1443
+ [MACRO] MAP_WITH_SEED %out_map, %seed
1444
+ %out_map = call @sa_map_with_seed(%seed)
1445
+ [END_MACRO]
1446
+
1447
+ [MACRO] MAP_WITH_CAPACITY %out_map, %cap
1448
+ %out_map = call @sa_map_with_capacity(%cap)
1449
+ [END_MACRO]
1450
+
1451
+ [MACRO] MAP_WITH_CAPACITY_SEED %out_map, %cap, %seed
1452
+ %out_map = call @sa_map_with_capacity_seed(%cap, %seed)
1453
+ [END_MACRO]
1454
+
1455
+ [MACRO] MAP_TRY_WITH_CAPACITY %out_ok, %out_map, %cap
1456
+ __map_try_new_slot_%out_ok = stack_alloc 8
1457
+ %out_ok = call @sa_map_try_with_capacity(%cap, &__map_try_new_slot_%out_ok)
1458
+ %out_map = load __map_try_new_slot_%out_ok+0 as ptr
1459
+ [END_MACRO]
1460
+
1461
+ [MACRO] MAP_LEN %out_len, %map_reg
1462
+ %out_len = call @sa_map_len(&%map_reg)
1463
+ [END_MACRO]
1464
+
1465
+ [MACRO] MAP_CAPACITY %out_cap, %map_reg
1466
+ %out_cap = call @sa_map_capacity(&%map_reg)
1467
+ [END_MACRO]
1468
+
1469
+ [MACRO] MAP_EXTRA_CAPACITY %out_extra, %map_reg
1470
+ __map_ec_cap_%out_extra = call @sa_map_capacity(&%map_reg)
1471
+ __map_ec_len_%out_extra = call @sa_map_len(&%map_reg)
1472
+ %out_extra = sub __map_ec_cap_%out_extra, __map_ec_len_%out_extra
1473
+ !__map_ec_len_%out_extra
1474
+ !__map_ec_cap_%out_extra
1475
+ [END_MACRO]
1476
+
1477
+ [MACRO] MAP_RESERVE %map_reg, %additional
1478
+ call @sa_map_reserve(&%map_reg, %additional)
1479
+ [END_MACRO]
1480
+
1481
+ [MACRO] MAP_TRY_RESERVE %out_ok, %map_reg, %additional
1482
+ %out_ok = call @sa_map_try_reserve(&%map_reg, %additional)
1483
+ [END_MACRO]
1484
+
1485
+ [MACRO] MAP_SHRINK_TO %map_reg, %min_capacity
1486
+ call @sa_map_shrink_to(&%map_reg, %min_capacity)
1487
+ [END_MACRO]
1488
+
1489
+ [MACRO] MAP_SHRINK_TO_FIT %map_reg
1490
+ call @sa_map_shrink_to_fit(&%map_reg)
1491
+ [END_MACRO]
1492
+
1493
+ [MACRO] MAP_IS_EMPTY %out_flag, %map_reg
1494
+ %out_flag = call @sa_map_is_empty(&%map_reg)
1495
+ [END_MACRO]
1496
+
1497
+ [MACRO] MAP_CONTAINS_KEY %out_flag, %map_reg, %key_reg
1498
+ %out_flag = call @sa_map_contains_key(&%map_reg, &%key_reg)
1499
+ [END_MACRO]
1500
+
1501
+ [MACRO] MAP_CLEAR %map_reg
1502
+ call @sa_map_clear(&%map_reg)
1503
+ [END_MACRO]
1504
+
1505
+ [MACRO] MAP_RETAIN %out_len, %map_reg, %pred_fn
1506
+ __map_retain_slots_%out_len = load %map_reg+HashMap_slots as ptr
1507
+ __map_retain_cap_%out_len = load %map_reg+HashMap_cap as u64
1508
+ __map_retain_len_%out_len = load %map_reg+HashMap_len as u64
1509
+ __map_retain_tombs_start_%out_len = load %map_reg+HashMap_tombs as u64
1510
+ __map_retain_len_slot_%out_len = stack_alloc 8
1511
+ __map_retain_tombs_slot_%out_len = stack_alloc 8
1512
+ store __map_retain_len_slot_%out_len+0, __map_retain_len_%out_len as u64
1513
+ store __map_retain_tombs_slot_%out_len+0, __map_retain_tombs_start_%out_len as u64
1514
+ __map_retain_idx_slot_%out_len = stack_alloc 8
1515
+ store __map_retain_idx_slot_%out_len+0, 0 as u64
1516
+ jmp L_MAP_RETAIN_HEAD_%out_len
1517
+
1518
+ L_MAP_RETAIN_HEAD_%out_len:
1519
+ __map_retain_idx_%out_len = load __map_retain_idx_slot_%out_len+0 as u64
1520
+ __map_retain_done_%out_len = eq __map_retain_idx_%out_len, __map_retain_cap_%out_len
1521
+ br __map_retain_done_%out_len -> L_MAP_RETAIN_DONE_%out_len, L_MAP_RETAIN_BODY_%out_len
1522
+
1523
+ L_MAP_RETAIN_BODY_%out_len:
1524
+ __map_retain_slot_off_%out_len = mul __map_retain_idx_%out_len, HashMapSlot_SIZE
1525
+ __map_retain_slot_%out_len = ptr_add __map_retain_slots_%out_len, __map_retain_slot_off_%out_len
1526
+ __map_retain_state_%out_len = load __map_retain_slot_%out_len+HashMapSlot_state as u8
1527
+ __map_retain_filled_%out_len = eq __map_retain_state_%out_len, HashMap_STATE_FILLED
1528
+ br __map_retain_filled_%out_len -> L_MAP_RETAIN_CHECK_%out_len, L_MAP_RETAIN_NEXT_%out_len
1529
+
1530
+ L_MAP_RETAIN_CHECK_%out_len:
1531
+ __map_retain_key_%out_len = load __map_retain_slot_%out_len+HashMapSlot_key as ptr
1532
+ __map_retain_value_ptr_%out_len = ptr_add __map_retain_slot_%out_len, HashMapSlot_value
1533
+ __map_retain_pred_%out_len = call %pred_fn(__map_retain_key_%out_len, __map_retain_value_ptr_%out_len)
1534
+ __map_retain_keep_%out_len = ne __map_retain_pred_%out_len, 0
1535
+ br __map_retain_keep_%out_len -> L_MAP_RETAIN_KEEP_%out_len, L_MAP_RETAIN_DROP_%out_len
1536
+
1537
+ L_MAP_RETAIN_KEEP_%out_len:
1538
+ !__map_retain_keep_%out_len
1539
+ !__map_retain_pred_%out_len
1540
+ !__map_retain_value_ptr_%out_len
1541
+ !__map_retain_key_%out_len
1542
+ jmp L_MAP_RETAIN_NEXT_%out_len
1543
+
1544
+ L_MAP_RETAIN_DROP_%out_len:
1545
+ __map_retain_cur_len_%out_len = load __map_retain_len_slot_%out_len+0 as u64
1546
+ __map_retain_cur_tombs_%out_len = load __map_retain_tombs_slot_%out_len+0 as u64
1547
+ __map_retain_next_len_%out_len = sub __map_retain_cur_len_%out_len, 1
1548
+ __map_retain_next_tombs_%out_len = add __map_retain_cur_tombs_%out_len, 1
1549
+ store __map_retain_len_slot_%out_len+0, __map_retain_next_len_%out_len as u64
1550
+ store __map_retain_tombs_slot_%out_len+0, __map_retain_next_tombs_%out_len as u64
1551
+ store __map_retain_slot_%out_len+HashMapSlot_hash, 0 as u64
1552
+ store __map_retain_slot_%out_len+HashMapSlot_key, 0 as ptr
1553
+ store __map_retain_slot_%out_len+HashMapSlot_value, 0 as ptr
1554
+ store __map_retain_slot_%out_len+HashMapSlot_state, HashMap_STATE_TOMB as u8
1555
+ !__map_retain_next_tombs_%out_len
1556
+ !__map_retain_next_len_%out_len
1557
+ !__map_retain_cur_tombs_%out_len
1558
+ !__map_retain_cur_len_%out_len
1559
+ !__map_retain_keep_%out_len
1560
+ !__map_retain_pred_%out_len
1561
+ !__map_retain_value_ptr_%out_len
1562
+ !__map_retain_key_%out_len
1563
+ jmp L_MAP_RETAIN_NEXT_%out_len
1564
+
1565
+ L_MAP_RETAIN_NEXT_%out_len:
1566
+ __map_retain_next_idx_%out_len = add __map_retain_idx_%out_len, 1
1567
+ store __map_retain_idx_slot_%out_len+0, __map_retain_next_idx_%out_len as u64
1568
+ !__map_retain_next_idx_%out_len
1569
+ !__map_retain_filled_%out_len
1570
+ !__map_retain_state_%out_len
1571
+ !__map_retain_slot_%out_len
1572
+ !__map_retain_slot_off_%out_len
1573
+ !__map_retain_done_%out_len
1574
+ !__map_retain_idx_%out_len
1575
+ jmp L_MAP_RETAIN_HEAD_%out_len
1576
+
1577
+ L_MAP_RETAIN_DONE_%out_len:
1578
+ %out_len = load __map_retain_len_slot_%out_len+0 as u64
1579
+ __map_retain_tombs_%out_len = load __map_retain_tombs_slot_%out_len+0 as u64
1580
+ store %map_reg+HashMap_len, %out_len as u64
1581
+ store %map_reg+HashMap_tombs, __map_retain_tombs_%out_len as u64
1582
+ !__map_retain_done_%out_len
1583
+ !__map_retain_idx_%out_len
1584
+ !__map_retain_tombs_%out_len
1585
+ !__map_retain_tombs_start_%out_len
1586
+ !__map_retain_len_%out_len
1587
+ !__map_retain_cap_%out_len
1588
+ !__map_retain_slots_%out_len
1589
+ [END_MACRO]
1590
+
1591
+ [MACRO] MAP_DRAIN %out_vec, %map_reg
1592
+ __map_drain_len_%out_vec = load %map_reg+HashMap_len as u64
1593
+ EXPAND NUM_U64_CHECKED_ADD __map_drain_cap_hint_ok_%out_vec, __map_drain_cap_hint_%out_vec, __map_drain_len_%out_vec, __map_drain_len_%out_vec
1594
+ br __map_drain_cap_hint_ok_%out_vec -> L_MAP_DRAIN_CAP_HINT_OK_%out_vec, L_MAP_DRAIN_CAP_HINT_OVERFLOW_%out_vec
1595
+ L_MAP_DRAIN_CAP_HINT_OVERFLOW_%out_vec:
1596
+ panic(1306)
1597
+ L_MAP_DRAIN_CAP_HINT_OK_%out_vec:
1598
+ EXPAND VEC_WITH_CAPACITY_U64 %out_vec, __map_drain_cap_hint_%out_vec
1599
+ __map_drain_slots_%out_vec = load %map_reg+HashMap_slots as ptr
1600
+ __map_drain_cap_%out_vec = load %map_reg+HashMap_cap as u64
1601
+ __map_drain_idx_slot_%out_vec = stack_alloc 8
1602
+ store __map_drain_idx_slot_%out_vec+0, 0 as u64
1603
+ jmp L_MAP_DRAIN_HEAD_%out_vec
1604
+
1605
+ L_MAP_DRAIN_HEAD_%out_vec:
1606
+ __map_drain_idx_%out_vec = load __map_drain_idx_slot_%out_vec+0 as u64
1607
+ __map_drain_done_%out_vec = eq __map_drain_idx_%out_vec, __map_drain_cap_%out_vec
1608
+ br __map_drain_done_%out_vec -> L_MAP_DRAIN_DONE_%out_vec, L_MAP_DRAIN_BODY_%out_vec
1609
+
1610
+ L_MAP_DRAIN_BODY_%out_vec:
1611
+ __map_drain_slot_off_%out_vec = mul __map_drain_idx_%out_vec, HashMapSlot_SIZE
1612
+ __map_drain_slot_%out_vec = ptr_add __map_drain_slots_%out_vec, __map_drain_slot_off_%out_vec
1613
+ __map_drain_state_%out_vec = load __map_drain_slot_%out_vec+HashMapSlot_state as u8
1614
+ __map_drain_filled_%out_vec = eq __map_drain_state_%out_vec, HashMap_STATE_FILLED
1615
+ br __map_drain_filled_%out_vec -> L_MAP_DRAIN_PUSH_%out_vec, L_MAP_DRAIN_NEXT_%out_vec
1616
+
1617
+ L_MAP_DRAIN_PUSH_%out_vec:
1618
+ __map_drain_key_%out_vec = load __map_drain_slot_%out_vec+HashMapSlot_key as ptr
1619
+ __map_drain_value_%out_vec = load __map_drain_slot_%out_vec+HashMapSlot_value as ptr
1620
+ __map_drain_key_bits_%out_vec = bitcast __map_drain_key_%out_vec as u64
1621
+ __map_drain_value_bits_%out_vec = bitcast __map_drain_value_%out_vec as u64
1622
+ EXPAND VEC_PUSH_U64 %out_vec, __map_drain_key_bits_%out_vec
1623
+ EXPAND VEC_PUSH_U64 %out_vec, __map_drain_value_bits_%out_vec
1624
+ store __map_drain_slot_%out_vec+HashMapSlot_hash, 0 as u64
1625
+ store __map_drain_slot_%out_vec+HashMapSlot_key, 0 as ptr
1626
+ store __map_drain_slot_%out_vec+HashMapSlot_value, 0 as ptr
1627
+ store __map_drain_slot_%out_vec+HashMapSlot_state, HashMap_STATE_EMPTY as u8
1628
+ !__map_drain_value_bits_%out_vec
1629
+ !__map_drain_key_bits_%out_vec
1630
+ !__map_drain_value_%out_vec
1631
+ !__map_drain_key_%out_vec
1632
+ jmp L_MAP_DRAIN_NEXT_%out_vec
1633
+
1634
+ L_MAP_DRAIN_NEXT_%out_vec:
1635
+ __map_drain_next_idx_%out_vec = add __map_drain_idx_%out_vec, 1
1636
+ store __map_drain_idx_slot_%out_vec+0, __map_drain_next_idx_%out_vec as u64
1637
+ !__map_drain_next_idx_%out_vec
1638
+ !__map_drain_filled_%out_vec
1639
+ !__map_drain_state_%out_vec
1640
+ !__map_drain_slot_%out_vec
1641
+ !__map_drain_slot_off_%out_vec
1642
+ !__map_drain_done_%out_vec
1643
+ !__map_drain_idx_%out_vec
1644
+ jmp L_MAP_DRAIN_HEAD_%out_vec
1645
+
1646
+ L_MAP_DRAIN_DONE_%out_vec:
1647
+ EXPAND NUM_U64_CHECKED_MUL __map_drain_bytes_ok_%out_vec, __map_drain_bytes_%out_vec, __map_drain_cap_%out_vec, HashMapSlot_SIZE
1648
+ br __map_drain_bytes_ok_%out_vec -> L_MAP_DRAIN_BYTES_OK_%out_vec, L_MAP_DRAIN_BYTES_OVERFLOW_%out_vec
1649
+ L_MAP_DRAIN_BYTES_OVERFLOW_%out_vec:
1650
+ panic(1307)
1651
+ L_MAP_DRAIN_BYTES_OK_%out_vec:
1652
+ __map_drain_has_slots_%out_vec = ne __map_drain_slots_%out_vec, 0
1653
+ br __map_drain_has_slots_%out_vec -> L_MAP_DRAIN_CLEAR_SLOTS_%out_vec, L_MAP_DRAIN_FINISH_%out_vec
1654
+
1655
+ L_MAP_DRAIN_CLEAR_SLOTS_%out_vec:
1656
+ call @sa_mem_set(&__map_drain_slots_%out_vec, 0, __map_drain_bytes_%out_vec)
1657
+ jmp L_MAP_DRAIN_FINISH_%out_vec
1658
+
1659
+ L_MAP_DRAIN_FINISH_%out_vec:
1660
+ store %map_reg+HashMap_len, 0 as u64
1661
+ store %map_reg+HashMap_tombs, 0 as u64
1662
+ !__map_drain_has_slots_%out_vec
1663
+ !__map_drain_bytes_ok_%out_vec
1664
+ !__map_drain_bytes_%out_vec
1665
+ !__map_drain_done_%out_vec
1666
+ !__map_drain_idx_%out_vec
1667
+ !__map_drain_cap_%out_vec
1668
+ !__map_drain_slots_%out_vec
1669
+ !__map_drain_cap_hint_ok_%out_vec
1670
+ !__map_drain_cap_hint_%out_vec
1671
+ !__map_drain_len_%out_vec
1672
+ [END_MACRO]
1673
+
1674
+ [MACRO] MAP_EXTRACT_IF %out_len, %out_vec, %map_reg, %pred_fn
1675
+ __map_extract_slots_%out_len = load %map_reg+HashMap_slots as ptr
1676
+ __map_extract_cap_%out_len = load %map_reg+HashMap_cap as u64
1677
+ __map_extract_len_%out_len = load %map_reg+HashMap_len as u64
1678
+ __map_extract_tombs_start_%out_len = load %map_reg+HashMap_tombs as u64
1679
+ EXPAND NUM_U64_CHECKED_ADD __map_extract_cap_hint_ok_%out_len, __map_extract_cap_hint_%out_len, __map_extract_len_%out_len, __map_extract_len_%out_len
1680
+ br __map_extract_cap_hint_ok_%out_len -> L_MAP_EXTRACT_CAP_HINT_OK_%out_len, L_MAP_EXTRACT_CAP_HINT_OVERFLOW_%out_len
1681
+ L_MAP_EXTRACT_CAP_HINT_OVERFLOW_%out_len:
1682
+ panic(1308)
1683
+ L_MAP_EXTRACT_CAP_HINT_OK_%out_len:
1684
+ EXPAND VEC_WITH_CAPACITY_U64 %out_vec, __map_extract_cap_hint_%out_len
1685
+ __map_extract_len_slot_%out_len = stack_alloc 8
1686
+ __map_extract_tombs_slot_%out_len = stack_alloc 8
1687
+ store __map_extract_len_slot_%out_len+0, __map_extract_len_%out_len as u64
1688
+ store __map_extract_tombs_slot_%out_len+0, __map_extract_tombs_start_%out_len as u64
1689
+ __map_extract_idx_slot_%out_len = stack_alloc 8
1690
+ store __map_extract_idx_slot_%out_len+0, 0 as u64
1691
+ jmp L_MAP_EXTRACT_HEAD_%out_len
1692
+
1693
+ L_MAP_EXTRACT_HEAD_%out_len:
1694
+ __map_extract_idx_%out_len = load __map_extract_idx_slot_%out_len+0 as u64
1695
+ __map_extract_done_%out_len = eq __map_extract_idx_%out_len, __map_extract_cap_%out_len
1696
+ br __map_extract_done_%out_len -> L_MAP_EXTRACT_DONE_%out_len, L_MAP_EXTRACT_BODY_%out_len
1697
+
1698
+ L_MAP_EXTRACT_BODY_%out_len:
1699
+ __map_extract_slot_off_%out_len = mul __map_extract_idx_%out_len, HashMapSlot_SIZE
1700
+ __map_extract_slot_%out_len = ptr_add __map_extract_slots_%out_len, __map_extract_slot_off_%out_len
1701
+ __map_extract_state_%out_len = load __map_extract_slot_%out_len+HashMapSlot_state as u8
1702
+ __map_extract_filled_%out_len = eq __map_extract_state_%out_len, HashMap_STATE_FILLED
1703
+ br __map_extract_filled_%out_len -> L_MAP_EXTRACT_CHECK_%out_len, L_MAP_EXTRACT_NEXT_%out_len
1704
+
1705
+ L_MAP_EXTRACT_CHECK_%out_len:
1706
+ __map_extract_key_%out_len = load __map_extract_slot_%out_len+HashMapSlot_key as ptr
1707
+ __map_extract_value_ptr_%out_len = ptr_add __map_extract_slot_%out_len, HashMapSlot_value
1708
+ __map_extract_pred_%out_len = call %pred_fn(__map_extract_key_%out_len, __map_extract_value_ptr_%out_len)
1709
+ __map_extract_take_%out_len = ne __map_extract_pred_%out_len, 0
1710
+ br __map_extract_take_%out_len -> L_MAP_EXTRACT_TAKE_%out_len, L_MAP_EXTRACT_KEEP_%out_len
1711
+
1712
+ L_MAP_EXTRACT_KEEP_%out_len:
1713
+ !__map_extract_take_%out_len
1714
+ !__map_extract_pred_%out_len
1715
+ !__map_extract_value_ptr_%out_len
1716
+ !__map_extract_key_%out_len
1717
+ jmp L_MAP_EXTRACT_NEXT_%out_len
1718
+
1719
+ L_MAP_EXTRACT_TAKE_%out_len:
1720
+ __map_extract_value_%out_len = load __map_extract_slot_%out_len+HashMapSlot_value as ptr
1721
+ __map_extract_key_bits_%out_len = bitcast __map_extract_key_%out_len as u64
1722
+ __map_extract_value_bits_%out_len = bitcast __map_extract_value_%out_len as u64
1723
+ EXPAND VEC_PUSH_U64 %out_vec, __map_extract_key_bits_%out_len
1724
+ EXPAND VEC_PUSH_U64 %out_vec, __map_extract_value_bits_%out_len
1725
+ __map_extract_cur_len_%out_len = load __map_extract_len_slot_%out_len+0 as u64
1726
+ __map_extract_cur_tombs_%out_len = load __map_extract_tombs_slot_%out_len+0 as u64
1727
+ __map_extract_next_len_%out_len = sub __map_extract_cur_len_%out_len, 1
1728
+ __map_extract_next_tombs_%out_len = add __map_extract_cur_tombs_%out_len, 1
1729
+ store __map_extract_len_slot_%out_len+0, __map_extract_next_len_%out_len as u64
1730
+ store __map_extract_tombs_slot_%out_len+0, __map_extract_next_tombs_%out_len as u64
1731
+ store __map_extract_slot_%out_len+HashMapSlot_hash, 0 as u64
1732
+ store __map_extract_slot_%out_len+HashMapSlot_key, 0 as ptr
1733
+ store __map_extract_slot_%out_len+HashMapSlot_value, 0 as ptr
1734
+ store __map_extract_slot_%out_len+HashMapSlot_state, HashMap_STATE_TOMB as u8
1735
+ !__map_extract_next_tombs_%out_len
1736
+ !__map_extract_next_len_%out_len
1737
+ !__map_extract_cur_tombs_%out_len
1738
+ !__map_extract_cur_len_%out_len
1739
+ !__map_extract_value_bits_%out_len
1740
+ !__map_extract_key_bits_%out_len
1741
+ !__map_extract_take_%out_len
1742
+ !__map_extract_pred_%out_len
1743
+ !__map_extract_value_%out_len
1744
+ !__map_extract_value_ptr_%out_len
1745
+ !__map_extract_key_%out_len
1746
+ jmp L_MAP_EXTRACT_NEXT_%out_len
1747
+
1748
+ L_MAP_EXTRACT_NEXT_%out_len:
1749
+ __map_extract_next_idx_%out_len = add __map_extract_idx_%out_len, 1
1750
+ store __map_extract_idx_slot_%out_len+0, __map_extract_next_idx_%out_len as u64
1751
+ !__map_extract_next_idx_%out_len
1752
+ !__map_extract_filled_%out_len
1753
+ !__map_extract_state_%out_len
1754
+ !__map_extract_slot_%out_len
1755
+ !__map_extract_slot_off_%out_len
1756
+ !__map_extract_done_%out_len
1757
+ !__map_extract_idx_%out_len
1758
+ jmp L_MAP_EXTRACT_HEAD_%out_len
1759
+
1760
+ L_MAP_EXTRACT_DONE_%out_len:
1761
+ %out_len = load __map_extract_len_slot_%out_len+0 as u64
1762
+ __map_extract_tombs_%out_len = load __map_extract_tombs_slot_%out_len+0 as u64
1763
+ store %map_reg+HashMap_len, %out_len as u64
1764
+ store %map_reg+HashMap_tombs, __map_extract_tombs_%out_len as u64
1765
+ !__map_extract_done_%out_len
1766
+ !__map_extract_idx_%out_len
1767
+ !__map_extract_tombs_%out_len
1768
+ !__map_extract_tombs_start_%out_len
1769
+ !__map_extract_cap_hint_ok_%out_len
1770
+ !__map_extract_cap_hint_%out_len
1771
+ !__map_extract_len_%out_len
1772
+ !__map_extract_cap_%out_len
1773
+ !__map_extract_slots_%out_len
1774
+ [END_MACRO]
1775
+
1776
+ [MACRO] MAP_PUT %map_reg, %key, %value
1777
+ call @sa_map_put(&%map_reg, &%key, &%value)
1778
+ [END_MACRO]
1779
+
1780
+ [MACRO] MAP_GET %out_value, %map_reg, %key
1781
+ %out_value = call @sa_map_get(&%map_reg, &%key)
1782
+ [END_MACRO]
1783
+
1784
+ [MACRO] MAP_TRY_GET %out_ok, %out_value, %map_reg, %key
1785
+ __map_try_get_slot_%out_ok = stack_alloc 8
1786
+ %out_ok = call @sa_map_try_get(&%map_reg, &%key, &__map_try_get_slot_%out_ok)
1787
+ %out_value = load __map_try_get_slot_%out_ok+0 as ptr
1788
+ [END_MACRO]
1789
+
1790
+ [MACRO] MAP_GET_KEY_VALUE %out_ok, %out_key, %out_value, %map_reg, %key
1791
+ __map_kv_key_slot_%out_ok = stack_alloc 8
1792
+ __map_kv_value_slot_%out_ok = stack_alloc 8
1793
+ %out_ok = call @sa_map_try_get_key_value(&%map_reg, &%key, &__map_kv_key_slot_%out_ok, &__map_kv_value_slot_%out_ok)
1794
+ %out_key = load __map_kv_key_slot_%out_ok+0 as ptr
1795
+ %out_value = load __map_kv_value_slot_%out_ok+0 as ptr
1796
+ [END_MACRO]
1797
+
1798
+ [MACRO] MAP_GET_MUT_PTR %out_ok, %out_ptr, %map_reg, %key
1799
+ __map_mut_slot_%out_ok = stack_alloc 8
1800
+ %out_ok = call @sa_map_get_mut_ptr(&%map_reg, &%key, &__map_mut_slot_%out_ok)
1801
+ %out_ptr = load __map_mut_slot_%out_ok+0 as ptr
1802
+ [END_MACRO]
1803
+
1804
+ [MACRO] MAP_TRY_GET_DISJOINT_MUT_PTRS %out_ok, %out_ptr_a, %out_ptr_b, %map_reg, %key_a, %key_b
1805
+ __map_disjoint_mut_a_slot_%out_ok = stack_alloc 8
1806
+ __map_disjoint_mut_b_slot_%out_ok = stack_alloc 8
1807
+ %out_ok = call @sa_map_try_get_disjoint_mut_ptrs(&%map_reg, &%key_a, &%key_b, &__map_disjoint_mut_a_slot_%out_ok, &__map_disjoint_mut_b_slot_%out_ok)
1808
+ %out_ptr_a = load __map_disjoint_mut_a_slot_%out_ok+0 as ptr
1809
+ %out_ptr_b = load __map_disjoint_mut_b_slot_%out_ok+0 as ptr
1810
+ [END_MACRO]
1811
+
1812
+ // Rust method-name aliases over checked disjoint mutable value-slot pointers.
1813
+ [MACRO] MAP_GET_DISJOINT_MUT_PTRS %out_ok, %out_ptr_a, %out_ptr_b, %map_reg, %key_a, %key_b
1814
+ EXPAND MAP_TRY_GET_DISJOINT_MUT_PTRS %out_ok, %out_ptr_a, %out_ptr_b, %map_reg, %key_a, %key_b
1815
+ [END_MACRO]
1816
+
1817
+ [MACRO] MAP_GET_DISJOINT_MUT %out_ok, %out_ptr_a, %out_ptr_b, %map_reg, %key_a, %key_b
1818
+ EXPAND MAP_TRY_GET_DISJOINT_MUT_PTRS %out_ok, %out_ptr_a, %out_ptr_b, %map_reg, %key_a, %key_b
1819
+ [END_MACRO]
1820
+
1821
+ [MACRO] MAP_INSERT %out_replaced, %out_old_value, %map_reg, %key, %value
1822
+ __map_insert_old_slot_%out_replaced = stack_alloc 8
1823
+ %out_replaced = call @sa_map_insert(&%map_reg, &%key, &%value, &__map_insert_old_slot_%out_replaced)
1824
+ %out_old_value = load __map_insert_old_slot_%out_replaced+0 as ptr
1825
+ [END_MACRO]
1826
+
1827
+ [MACRO] MAP_TRY_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, %value
1828
+ __map_try_insert_ptr_slot_%out_inserted = stack_alloc 8
1829
+ %out_inserted = call @sa_map_try_insert(&%map_reg, &%key, &%value, &__map_try_insert_ptr_slot_%out_inserted)
1830
+ %out_value_ptr = load __map_try_insert_ptr_slot_%out_inserted+0 as ptr
1831
+ [END_MACRO]
1832
+
1833
+ [MACRO] MAP_ENTRY_OR_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, %value
1834
+ EXPAND MAP_TRY_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, %value
1835
+ [END_MACRO]
1836
+
1837
+ // Rust method-name bare alias for the common entry path (or_insert).
1838
+ [MACRO] MAP_ENTRY %out_inserted, %out_value_ptr, %map_reg, %key, %value
1839
+ EXPAND MAP_ENTRY_OR_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, %value
1840
+ [END_MACRO]
1841
+
1842
+ [MACRO] MAP_OR_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, %value
1843
+ EXPAND MAP_ENTRY_OR_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, %value
1844
+ [END_MACRO]
1845
+
1846
+ // Concrete entry-style helpers over try-insert / get-mut-ptr.
1847
+ // Default inserted value is a null pointer (0). and_modify stores only when present.
1848
+
1849
+ [MACRO] MAP_ENTRY_OR_DEFAULT %out_inserted, %out_value_ptr, %map_reg, %key
1850
+ __map_entry_default_%out_inserted = add 0, 0
1851
+ EXPAND MAP_ENTRY_OR_INSERT %out_inserted, %out_value_ptr, %map_reg, %key, __map_entry_default_%out_inserted
1852
+ !__map_entry_default_%out_inserted
1853
+ [END_MACRO]
1854
+
1855
+ [MACRO] MAP_ENTRY_AND_MODIFY %out_ok, %map_reg, %key, %value
1856
+ __map_and_mod_ptr_slot_%out_ok = stack_alloc 8
1857
+ %out_ok = call @sa_map_get_mut_ptr(&%map_reg, &%key, &__map_and_mod_ptr_slot_%out_ok)
1858
+ __map_and_mod_ptr_%out_ok = load __map_and_mod_ptr_slot_%out_ok+0 as ptr
1859
+ __map_and_mod_has_%out_ok = eq %out_ok, 1
1860
+ br __map_and_mod_has_%out_ok -> L_MAP_ENTRY_AND_MODIFY_SET_%out_ok, L_MAP_ENTRY_AND_MODIFY_SKIP_%out_ok
1861
+ L_MAP_ENTRY_AND_MODIFY_SET_%out_ok:
1862
+ store __map_and_mod_ptr_%out_ok+0, %value as ptr
1863
+ !__map_and_mod_has_%out_ok
1864
+ !__map_and_mod_ptr_%out_ok
1865
+ jmp L_MAP_ENTRY_AND_MODIFY_END_%out_ok
1866
+ L_MAP_ENTRY_AND_MODIFY_SKIP_%out_ok:
1867
+ !__map_and_mod_has_%out_ok
1868
+ !__map_and_mod_ptr_%out_ok
1869
+ jmp L_MAP_ENTRY_AND_MODIFY_END_%out_ok
1870
+ L_MAP_ENTRY_AND_MODIFY_END_%out_ok:
1871
+ [END_MACRO]
1872
+
1873
+ [MACRO] MAP_KEYS %out_vec, %map_reg
1874
+ %out_vec = call @sa_map_keys_vec(&%map_reg)
1875
+ [END_MACRO]
1876
+
1877
+ [MACRO] MAP_VALUES %out_vec, %map_reg
1878
+ %out_vec = call @sa_map_values_vec(&%map_reg)
1879
+ [END_MACRO]
1880
+
1881
+ [MACRO] MAP_INTO_KEYS %out_vec, %map_reg
1882
+ EXPAND MAP_KEYS %out_vec, %map_reg
1883
+ EXPAND MAP_CLEAR %map_reg
1884
+ [END_MACRO]
1885
+
1886
+ [MACRO] MAP_INTO_VALUES %out_vec, %map_reg
1887
+ EXPAND MAP_VALUES %out_vec, %map_reg
1888
+ EXPAND MAP_CLEAR %map_reg
1889
+ [END_MACRO]
1890
+
1891
+ [MACRO] MAP_VALUES_MUT_PTRS %out_vec, %map_reg
1892
+ %out_vec = call @sa_map_value_mut_ptrs_vec(&%map_reg)
1893
+ [END_MACRO]
1894
+
1895
+ [MACRO] MAP_VALUES_MUT %out_vec, %map_reg
1896
+ EXPAND MAP_VALUES_MUT_PTRS %out_vec, %map_reg
1897
+ [END_MACRO]
1898
+
1899
+ [MACRO] MAP_ITER %out_vec, %map_reg
1900
+ %out_vec = call @sa_map_iter_vec(&%map_reg)
1901
+ [END_MACRO]
1902
+
1903
+ [MACRO] MAP_ITER_MUT_PTRS %out_vec, %map_reg
1904
+ %out_vec = call @sa_map_iter_mut_ptrs_vec(&%map_reg)
1905
+ [END_MACRO]
1906
+
1907
+ // Rust method-name alias: HashMap::iter_mut (eager raw value-slot pointer materialization).
1908
+ [MACRO] MAP_ITER_MUT %out_vec, %map_reg
1909
+ EXPAND MAP_ITER_MUT_PTRS %out_vec, %map_reg
1910
+ [END_MACRO]
1911
+
1912
+ [MACRO] MAP_REF_INTO_ITER %out_vec, %map_reg
1913
+ EXPAND MAP_ITER %out_vec, %map_reg
1914
+ [END_MACRO]
1915
+
1916
+ [MACRO] MAP_MUT_REF_INTO_ITER %out_vec, %map_reg
1917
+ EXPAND MAP_ITER_MUT_PTRS %out_vec, %map_reg
1918
+ [END_MACRO]
1919
+
1920
+ [MACRO] MAP_INTO_ITER %out_vec, %map_reg
1921
+ EXPAND MAP_DRAIN %out_vec, %map_reg
1922
+ [END_MACRO]
1923
+
1924
+ [MACRO] MAP_REMOVE_ENTRY %out_ok, %out_key, %out_value, %map_reg, %key
1925
+ __map_remove_key_slot_%out_ok = stack_alloc 8
1926
+ __map_remove_value_slot_%out_ok = stack_alloc 8
1927
+ %out_ok = call @sa_map_remove_entry(&%map_reg, &%key, &__map_remove_key_slot_%out_ok, &__map_remove_value_slot_%out_ok)
1928
+ %out_key = load __map_remove_key_slot_%out_ok+0 as ptr
1929
+ %out_value = load __map_remove_value_slot_%out_ok+0 as ptr
1930
+ [END_MACRO]
1931
+
1932
+ [MACRO] MAP_DEL %out_value, %map_reg, %key
1933
+ %out_value = call @sa_map_del(&%map_reg, &%key)
1934
+ [END_MACRO]
1935
+
1936
+ [MACRO] MAP_FREE %map_reg
1937
+ call @sa_map_free(^%map_reg)
1938
+ [END_MACRO]
1939
+
1940
+ [MACRO] MAP_LIT1 %out_map, %key1, %value1
1941
+ EXPAND MAP_NEW %out_map
1942
+ EXPAND MAP_PUT %out_map, %key1, %value1
1943
+ [END_MACRO]
1944
+
1945
+ [MACRO] MAP_LIT2 %out_map, %key1, %value1, %key2, %value2
1946
+ EXPAND MAP_NEW %out_map
1947
+ EXPAND MAP_PUT %out_map, %key1, %value1
1948
+ EXPAND MAP_PUT %out_map, %key2, %value2
1949
+ [END_MACRO]
1950
+
1951
+ [MACRO] MAP_LIT3 %out_map, %key1, %value1, %key2, %value2, %key3, %value3
1952
+ EXPAND MAP_NEW %out_map
1953
+ EXPAND MAP_PUT %out_map, %key1, %value1
1954
+ EXPAND MAP_PUT %out_map, %key2, %value2
1955
+ EXPAND MAP_PUT %out_map, %key3, %value3
1956
+ [END_MACRO]
1957
+
1958
+ // Rust Default-style empty map constructor alias.
1959
+
1960
+ [MACRO] MAP_DEFAULT %out_map
1961
+ EXPAND MAP_NEW %out_map
1962
+ [END_MACRO]