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
|
|
@ -306,13 +306,24 @@
|
|||
(loop (cddr a)))))
|
||||
jolt-nil)
|
||||
|
||||
;; alter-meta! / reset-meta!: update a var's metadata (var-meta-table, rt.ss).
|
||||
;; alter-meta! / reset-meta!: a var's metadata lives in var-meta-table (rt.ss);
|
||||
;; any other reference (atom/agent/namespace) uses the identity meta side-table
|
||||
;; jolt-meta reads.
|
||||
(define (jolt-alter-meta! ref f . args)
|
||||
(let* ((cur (or (hashtable-ref var-meta-table ref #f) (jolt-hash-map)))
|
||||
(new (apply jolt-invoke f cur args)))
|
||||
(hashtable-set! var-meta-table ref new)
|
||||
new))
|
||||
(define (jolt-reset-meta! ref m) (hashtable-set! var-meta-table ref m) m)
|
||||
(if (var-cell? ref)
|
||||
(let* ((cur (or (hashtable-ref var-meta-table ref #f) (jolt-hash-map)))
|
||||
(new (apply jolt-invoke f cur args)))
|
||||
(hashtable-set! var-meta-table ref new)
|
||||
new)
|
||||
(let* ((cur (let ((m (jolt-meta ref))) (if (jolt-nil? m) (jolt-hash-map) m)))
|
||||
(new (apply jolt-invoke f cur args)))
|
||||
(hashtable-set! meta-table ref new)
|
||||
new)))
|
||||
(define (jolt-reset-meta! ref m)
|
||||
(if (var-cell? ref)
|
||||
(hashtable-set! var-meta-table ref m)
|
||||
(hashtable-set! meta-table ref m))
|
||||
m)
|
||||
|
||||
;; --- RESOLVE FRICTION: native-op cells -------------------------------------
|
||||
;; Native-op primitives (+ map reduce …) are INLINED at emit, so they have no
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue