^long is a 64-bit long: fast-path-with-fallback ops + logical unsigned shift
Completes the JVM long-compatibility gap so clojure.test.check (and the property-based suites built on it, e.g. data.codec) run on jolt. A ^long is 64-bit but a Chez fixnum is only 61-bit, so the backend's fast fx comparison / quot / min / max / inc / dec ops raised on a full-width long (one from the PRNG or wrapping arithmetic). They now go through the jolt-l* macros (host/chez/seq.ss): the fx fast path when the operands ARE fixnums, the generic op otherwise — so e.g. ((fn [^long a ^long b] (< a b)) Long/MAX 1) is false, not an error. Arithmetic +/-/* keep the raw fx ops (under *unchecked-math* they're already the wrapping unchecked-*). Also fixes unsigned-bit-shift-right: it was an arithmetic (sign-propagating) shift, now a logical shift over the 64-bit two's-complement window, so (unsigned-bit-shift-right -1 1) is 2^63-1 like the JVM. Result: test.check 1.1.3 loads and runs (generators, quick-check, shrinking); data.codec's base64 property suite passes (12/12 defspecs; the 2 deftests check clojure.lang.IFn$OLLOL, a JVM primitive-fn interface, N/A). Both added to docs/libraries.md + the site. re-mint (backend/seed). make test green (+3 corpus rows, 0 new divergences, numeric gate updated to the jolt-l* ops), shakesmoke byte-identical.
This commit is contained in:
parent
a028cab04f
commit
3340635714
7 changed files with 62 additions and 20 deletions
|
|
@ -180,6 +180,32 @@
|
|||
;; the clojure.core/unchecked-* vars are def-var!'d in natives-seq.ss (def-var! is
|
||||
;; defined after this file loads).
|
||||
|
||||
;; --- ^long ops that tolerate a full 64-bit value -----------------------------
|
||||
;; A ^long is 64-bit but a Chez fixnum is only 61-bit, so the backend's fast fx
|
||||
;; ops would raise on a value past 2^60 (e.g. a long from the PRNG / wrapping
|
||||
;; arithmetic). These take the fx fast path when the operands ARE fixnums and fall
|
||||
;; back to the generic op otherwise — so ^long comparisons / quot / min etc. on a
|
||||
;; full-width long stay correct. Macros (define-syntax) so the fast path inlines.
|
||||
(define-syntax define-l-binop
|
||||
(syntax-rules ()
|
||||
((_ name fxop genop)
|
||||
(define-syntax name
|
||||
(syntax-rules ()
|
||||
((_ a b) (let ((x a) (y b))
|
||||
(if (and (fixnum? x) (fixnum? y)) (fxop x y) (genop x y)))))))))
|
||||
(define-l-binop jolt-l< fx<? <)
|
||||
(define-l-binop jolt-l<= fx<=? <=)
|
||||
(define-l-binop jolt-l> fx>? >)
|
||||
(define-l-binop jolt-l>= fx>=? >=)
|
||||
(define-l-binop jolt-l= fx=? =)
|
||||
(define-l-binop jolt-l-min fxmin min)
|
||||
(define-l-binop jolt-l-max fxmax max)
|
||||
(define-l-binop jolt-l-quot fxquotient quotient)
|
||||
(define-l-binop jolt-l-rem fxremainder remainder)
|
||||
(define-l-binop jolt-l-mod fxmodulo modulo)
|
||||
(define-syntax jolt-l-inc (syntax-rules () ((_ a) (let ((x a)) (if (fixnum? x) (fx1+ x) (+ x 1))))))
|
||||
(define-syntax jolt-l-dec (syntax-rules () ((_ a) (let ((x a)) (if (fixnum? x) (fx1- x) (- x 1))))))
|
||||
|
||||
;; ============================================================================
|
||||
;; IFn dispatch — the dynamic "value as fn" fallback. A callee that the emitter
|
||||
;; can't statically resolve to a procedure (a keyword/coll/proc held in a local)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue