Bare-index field reads for statically-known records (#228)
When the inference types a keyword-lookup receiver as a record — it carries the field-order :shape and :hint :struct from the whole-program fixpoint — the back end reads the field by its declared slot via jrec-field-at instead of jolt-get. That skips the jolt-get case-lambda, the dispatch fn, and the field-key hashtable lookup, leaving a jrec? check + a static-index vector-ref. jrec-field-at falls back to jolt-get when the receiver isn't the expected record (a map downgraded by dissoc, or a value the inference mistyped), so it stays correct if the static type is wrong. Only the no-default form takes the bare path (a declared field is always present). Sound only for non-nil records: a self-recursive param that can be nil (e.g. binary-trees check-tree, whose untagged child is nil at leaves) types :any and keeps jolt-get — the whole-program fixpoint demotes it. The target is non-nil record params, like a Vec3 dot product (~5% there; boxed-flonum arithmetic dominates the rest, a separate numeric lever). run-fieldread.ss gate: emitted form uses jrec-field-at at the right slot and matches jolt-get for each declared field; a non-field key and a default-arg form keep the generic path. make test / shakesmoke green, 0 new divergences. Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
parent
af11aaa7ff
commit
de31221573
5 changed files with 188 additions and 80 deletions
|
|
@ -146,6 +146,17 @@
|
|||
=> (lambda (m) (jolt-invoke m coll k d)))
|
||||
(else d))
|
||||
v))))))
|
||||
;; bare-index field read for a statically-known record field — emitted by `jolt
|
||||
;; build --opt` for a struct-typed receiver, where i is the field's declared slot.
|
||||
;; When r is the expected record it reads the value vector directly: no field-key
|
||||
;; hashtable lookup, no jolt-get dispatch. Falls back to jolt-get otherwise (a map
|
||||
;; downgraded by dissoc, or a value the inference mistyped), so it stays correct
|
||||
;; even if the static type is wrong.
|
||||
(define (jrec-field-at r i k)
|
||||
(if (and (jrec? r) (fx< i (vector-length (jrec-vals r))))
|
||||
(vector-ref (jrec-vals r) i)
|
||||
(jolt-get r k)))
|
||||
|
||||
;; mutate a deftype's mutable field in place: the value vector is mutable, so
|
||||
;; vector-set! updates the field. (set! field v) inside a method lowers to this;
|
||||
;; returns v, as set! does.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue