One IRef seam: watches/validators/meta over atom, var, and agent
add-watch/remove-watch/set-validator!/get-validator were atom-only; the atom ctor ignored :meta and :validator; watching a var crashed. Now the ARef contract is one seam: atoms keep their record slots (hot path unchanged), every other reference type registers a predicate and stores watches/validators in identity-keyed side tables, and notifies at its mutation points. Vars notify on root changes (def on a watched var, var-set outside a thread binding, alter-var-root — thread-binding sets don't notify, like the JVM); agents notify per action. The def-var! wrap costs two weak-table probes per def and does IRef work only on a watched var. Ctor options follow ARef: the validator gates the initial value (IllegalStateException 'Invalid reference state' — also the class for rejected swap!/reset!), :meta must be a map (else ClassCastException), nil allowed. meta reads any reference through the identity side-table (the type-gated fall-through is gone); alter-meta!/reset-meta! work on non-var references. Runtime-only (no re-mint). 9 JVM-certified corpus rows; spec entry; cts baseline 5781 -> 5805 pass, 73 baselined namespaces (the residual error in the watch namespaces is their STM ref section — refs stay out of scope).
This commit is contained in:
parent
257f822825
commit
f80f9aab4b
8 changed files with 203 additions and 42 deletions
|
|
@ -77,14 +77,23 @@
|
|||
(let ((p (dyn-find-binding v)))
|
||||
(if p
|
||||
(begin (set-cdr! p val) val)
|
||||
(begin (var-cell-root-set! v val) (var-cell-defined?-set! v #t) val)))
|
||||
;; a ROOT change is Var.bindRoot: validate, set, notify watches
|
||||
;; (a thread-binding set does not notify, like the JVM).
|
||||
(let ((old (var-cell-root v)))
|
||||
(iref-validate v val)
|
||||
(var-cell-root-set! v val) (var-cell-defined?-set! v #t)
|
||||
(iref-notify v old val)
|
||||
val)))
|
||||
(error #f "var-set: not a var" v)))
|
||||
|
||||
;; alter-var-root: atomically apply f to the current root plus args.
|
||||
(define (jolt-alter-var-root v f . args)
|
||||
(let ((new (apply jolt-invoke f (var-cell-root v) args)))
|
||||
(let* ((old (var-cell-root v))
|
||||
(new (apply jolt-invoke f old args)))
|
||||
(iref-validate v new)
|
||||
(var-cell-root-set! v new)
|
||||
(var-cell-defined?-set! v #t)
|
||||
(iref-notify v old new)
|
||||
new))
|
||||
|
||||
;; __local-var: a fresh free-standing var cell (not interned). with-local-vars
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue