maps.flan and map-exhausted.flan as fixed-output cases, the six refusals
by name, and map-stale-region.flan beside stale-region.flan.
The last one is not a line in the Vec's program because the two reach
the check by different routes. A Vec's operations check on the way in
and stop there. A map's get goes on to call a hash and an equality
function through pointers into the block, so a missing check there is
not a wrong number — it is a probe loop walking released memory. It
traps naming the site and exits 134, as the Vec's does.
{K V} resolves now, so the test that asserted it was milestone 6 is
replaced by the one that still holds: the arity, refused for the reason
Vec's arity is refused, because a near-miss would otherwise resolve to a
type variable and come back as generics.
26 lines
1.2 KiB
Plaintext
26 lines
1.2 KiB
Plaintext
;;;; spec-memory.md, "Dev builds detect a released region" — the Map's half.
|
|
;;;;
|
|
;;;; A Map records the epoch of the allocator it was made with, exactly as a
|
|
;;;; Vec does, and free-all bumps that counter. Any operation on a container
|
|
;;;; whose recorded epoch has moved traps, naming the site.
|
|
;;;;
|
|
;;;; This is worth its own program rather than a line in stale-region.flan
|
|
;;;; because the two containers reach the check by different routes: a Vec's
|
|
;;;; every operation takes the Vec's address and checks on the way in, while a
|
|
;;;; map's get goes on to call a hash and an equality function through pointers
|
|
;;;; into a block that is no longer there. If the check were missing here, the
|
|
;;;; failure would not be a wrong number — it would be a probe loop walking
|
|
;;;; released memory.
|
|
(defn main [] i32
|
|
(let [a (arena-new 65536)]
|
|
(let [m (map-new i32 i32 a)]
|
|
(put m 1 10)
|
|
(put m 2 20)
|
|
(match (get m 2) (Some v) (println v) None (println "missing"))
|
|
;; The region goes. m is still in scope and still looks fine — nothing is
|
|
;; released at scope exit and nothing marked m — which is exactly the
|
|
;; case a static rule cannot see.
|
|
(free-all a)
|
|
(match (get m 2) (Some v) (println v) None (println "missing"))))
|
|
0)
|