The refusals: the arities, a pool of an owning element, ordering handles, free of a handle, and clone of a pool. Each names what it would cost — a cloned pool duplicates the generation counters with the slots, so one handle would resolve in both copies and name two different things. pool-stale-region.flan is the other failure, and the point of it is that it is not the first. A stale handle is an answer and resolve says None; a pool whose region was released has no slot array left to ask, so it traps. Same rule that keeps a Vec's generation word and its epoch word apart.
26 lines
1.1 KiB
Plaintext
26 lines
1.1 KiB
Plaintext
;;;; The epoch trap on the pool's side. spec-memory.md, "Dev builds detect a
|
|
;;;; released region".
|
|
;;;;
|
|
;;;; This is deliberately the *other* failure from a stale handle, and the two
|
|
;;;; must not be conflated — the same rule that keeps a Vec's generation word
|
|
;;;; and its epoch word apart. A stale handle is an answer: the entity died,
|
|
;;;; resolve says None, the program carries on. A released region is not an
|
|
;;;; answer at all: the storage the pool sits in is gone, the slot array with
|
|
;;;; it, and there is nothing left to ask. So one returns None and the other
|
|
;;;; traps naming the site.
|
|
(defn main [] i32
|
|
(let [a (arena-new 4096)]
|
|
(let [p (pool-new i32 a)]
|
|
(let [h (insert p 7)]
|
|
(match (resolve p h)
|
|
(Some x) (println (deref x))
|
|
None (println -1))
|
|
;; The region goes. p is still in scope, still looks fine, and h is
|
|
;; still a perfectly well-formed handle — which is exactly the case a
|
|
;; static rule cannot see.
|
|
(free-all a)
|
|
(match (resolve p h)
|
|
(Some x) (println (deref x))
|
|
None (println -1)))))
|
|
0)
|